1 /* $NetBSD: if_ray.c,v 1.37 2003/02/23 04:15:02 simonb 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.37 2003/02/23 04:15:02 simonb 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 ray_cmd_func_t rcmd; 1951 u_int cmd, stat; 1952 1953 cmd = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_cmd); 1954 stat = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status); 1955 1956 RAY_DPRINTF(("%s: ray_ccs_done idx %ld cmd 0x%x stat %d\n", 1957 sc->sc_xname, RAY_GET_INDEX(ccs), cmd, stat)); 1958 1959 rcmd = 0; 1960 switch (cmd) { 1961 /* 1962 * solicited commands 1963 */ 1964 case RAY_CMD_START_PARAMS: 1965 /* start network */ 1966 ray_cmd_done(sc, SCP_UPD_STARTUP); 1967 1968 /* ok to start queueing packets */ 1969 sc->sc_if.if_flags &= ~IFF_OACTIVE; 1970 1971 sc->sc_omode = sc->sc_mode; 1972 memcpy(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid)); 1973 1974 rcmd = ray_start_join_net; 1975 break; 1976 case RAY_CMD_UPDATE_PARAMS: 1977 rcmd = ray_update_params_done(sc, ccs, stat); 1978 break; 1979 case RAY_CMD_REPORT_PARAMS: 1980 /* get the reported parameters */ 1981 ray_cmd_done(sc, SCP_REPORTPARAMS); 1982 if (!sc->sc_repreq) 1983 break; 1984 sc->sc_repreq->r_failcause = 1985 SRAM_READ_FIELD_1(sc, ccs, ray_cmd_report, c_failcause); 1986 sc->sc_repreq->r_len = 1987 SRAM_READ_FIELD_1(sc, ccs, ray_cmd_report, c_len); 1988 ray_read_region(sc, RAY_ECF_TO_HOST_BASE, sc->sc_repreq->r_data, 1989 sc->sc_repreq->r_len); 1990 sc->sc_repreq = 0; 1991 wakeup(ray_report_params); 1992 break; 1993 case RAY_CMD_UPDATE_MCAST: 1994 ray_cmd_done(sc, SCP_UPD_MCAST); 1995 if (stat == RAY_CCS_STATUS_FAIL) 1996 rcmd = ray_reset; 1997 break; 1998 case RAY_CMD_START_NET: 1999 case RAY_CMD_JOIN_NET: 2000 rcmd = ray_start_join_net_done(sc, cmd, ccs, stat); 2001 break; 2002 case RAY_CMD_TX_REQ: 2003 if (sc->sc_if.if_flags & IFF_OACTIVE) { 2004 sc->sc_if.if_flags &= ~IFF_OACTIVE; 2005 /* this may also be a problem */ 2006 rcmd = ray_intr_start; 2007 } 2008 /* free it -- no tracking */ 2009 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status, 2010 RAY_CCS_STATUS_FREE); 2011 goto done; 2012 case RAY_CMD_START_ASSOC: 2013 ray_cmd_done(sc, SCP_STARTASSOC); 2014 if (stat == RAY_CCS_STATUS_FAIL) 2015 rcmd = ray_start_join_net; /* XXX check */ 2016 else { 2017 sc->sc_havenet = 1; 2018 rcmd = ray_intr_start; 2019 } 2020 break; 2021 case RAY_CMD_UPDATE_APM: 2022 case RAY_CMD_TEST_MEM: 2023 case RAY_CMD_SHUTDOWN: 2024 case RAY_CMD_DUMP_MEM: 2025 case RAY_CMD_START_TIMER: 2026 break; 2027 default: 2028 printf("%s: intr: unknown command 0x%x\n", 2029 sc->sc_if.if_xname, cmd); 2030 break; 2031 } 2032 ray_free_ccs(sc, ccs); 2033 done: 2034 /* 2035 * see if needed things can be done now that a command 2036 * has completed 2037 */ 2038 ray_check_scheduled(sc); 2039 2040 return (rcmd); 2041 } 2042 2043 /* 2044 * an unsolicted interrupt, i.e., the ECF is sending us a command 2045 */ 2046 static ray_cmd_func_t 2047 ray_rccs_intr(sc, ccs) 2048 struct ray_softc *sc; 2049 bus_size_t ccs; 2050 { 2051 ray_cmd_func_t rcmd; 2052 u_int cmd, stat; 2053 2054 cmd = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_cmd); 2055 stat = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status); 2056 2057 RAY_DPRINTF(("%s: ray_rccs_intr idx %ld cmd 0x%x stat %d\n", 2058 sc->sc_xname, RAY_GET_INDEX(ccs), cmd, stat)); 2059 2060 rcmd = 0; 2061 switch (cmd) { 2062 /* 2063 * unsolicted commands 2064 */ 2065 case RAY_ECMD_RX_DONE: 2066 ray_recv(sc, ccs); 2067 goto done; 2068 case RAY_ECMD_REJOIN_DONE: 2069 if (sc->sc_mode == SC_MODE_ADHOC) 2070 break; 2071 /* get the current ssid */ 2072 SRAM_READ_FIELD_N(sc, ccs, ray_cmd_net, c_bss_id, 2073 sc->sc_bssid, sizeof(sc->sc_bssid)); 2074 rcmd = ray_start_assoc; 2075 break; 2076 case RAY_ECMD_ROAM_START: 2077 /* no longer have network */ 2078 sc->sc_havenet = 0; 2079 break; 2080 case RAY_ECMD_JAPAN_CALL_SIGNAL: 2081 break; 2082 default: 2083 ray_update_error_counters(sc); 2084 2085 /* this is a bogus return from build 4 don't free 0x55 */ 2086 if (sc->sc_version == SC_BUILD_4 && cmd == 0x55 2087 && RAY_GET_INDEX(ccs) == 0x55) { 2088 goto done; 2089 } 2090 printf("%s: intr: unknown command 0x%x\n", 2091 sc->sc_if.if_xname, cmd); 2092 break; 2093 } 2094 /* free the ccs */ 2095 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status, RAY_CCS_STATUS_FREE); 2096 done: 2097 return (rcmd); 2098 } 2099 2100 /* 2101 * process an interrupt 2102 */ 2103 static int 2104 ray_intr(arg) 2105 void *arg; 2106 { 2107 struct ray_softc *sc; 2108 ray_cmd_func_t rcmd; 2109 u_int i, count; 2110 2111 sc = arg; 2112 2113 RAY_DPRINTF(("%s: ray_intr\n", sc->sc_xname)); 2114 2115 if ((++sc->sc_checkcounters % 32) == 0) 2116 ray_update_error_counters(sc); 2117 2118 count = 0; 2119 rcmd = 0; 2120 if (!REG_READ(sc, RAY_HCSIR)) 2121 count = 0; 2122 else { 2123 count = 1; 2124 i = SRAM_READ_1(sc, RAY_SCB_RCCSI); 2125 if (i <= RAY_CCS_LAST) 2126 rcmd = ray_ccs_done(sc, RAY_GET_CCS(i)); 2127 else if (i <= RAY_RCCS_LAST) 2128 rcmd = ray_rccs_intr(sc, RAY_GET_CCS(i)); 2129 else 2130 printf("%s: intr: bad cmd index %d\n", sc->sc_xname, i); 2131 } 2132 2133 if (rcmd) 2134 (*rcmd)(sc); 2135 2136 if (count) 2137 REG_WRITE(sc, RAY_HCSIR, 0); 2138 2139 RAY_DPRINTF(("%s: interrupt handled %d\n", sc->sc_xname, count)); 2140 2141 return (count ? 1 : 0); 2142 } 2143 2144 2145 /* 2146 * Generic CCS handling 2147 */ 2148 2149 /* 2150 * free the chain of descriptors -- used for freeing allocated tx chains 2151 */ 2152 static void 2153 ray_free_ccs_chain(sc, ni) 2154 struct ray_softc *sc; 2155 u_int ni; 2156 { 2157 u_int i; 2158 2159 while ((i = ni) != RAY_CCS_LINK_NULL) { 2160 ni = SRAM_READ_FIELD_1(sc, RAY_GET_CCS(i), ray_cmd, c_link); 2161 SRAM_WRITE_FIELD_1(sc, RAY_GET_CCS(i), ray_cmd, c_status, 2162 RAY_CCS_STATUS_FREE); 2163 } 2164 } 2165 2166 /* 2167 * free up a cmd and return the old status 2168 * this routine is only used for commands 2169 */ 2170 static u_int8_t 2171 ray_free_ccs(sc, ccs) 2172 struct ray_softc *sc; 2173 bus_size_t ccs; 2174 { 2175 u_int8_t stat; 2176 2177 RAY_DPRINTF(("%s: free_ccs idx %ld\n", sc->sc_xname, 2178 RAY_GET_INDEX(ccs))); 2179 2180 stat = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status); 2181 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status, RAY_CCS_STATUS_FREE); 2182 if (ccs <= RAY_GET_CCS(RAY_CCS_LAST)) 2183 sc->sc_ccsinuse[RAY_GET_INDEX(ccs)] = 0; 2184 2185 return (stat); 2186 } 2187 2188 /* 2189 * returns 1 and in `ccb' the bus offset of the free ccb 2190 * or 0 if none are free 2191 * 2192 * If `track' is not zero, handles tracking this command 2193 * possibly indicating a callback is needed and setting a timeout 2194 * also if ECF isn't ready we terminate earlier to avoid overhead. 2195 * 2196 * this routine is only used for commands 2197 */ 2198 static int 2199 ray_alloc_ccs(sc, ccsp, cmd, track) 2200 struct ray_softc *sc; 2201 bus_size_t *ccsp; 2202 u_int cmd, track; 2203 { 2204 bus_size_t ccs; 2205 u_int i; 2206 2207 RAY_DPRINTF(("%s: alloc_ccs cmd %d\n", sc->sc_xname, cmd)); 2208 2209 /* for tracked commands, if not ready just set pending */ 2210 if (track && !RAY_ECF_READY(sc)) { 2211 ray_cmd_schedule(sc, track); 2212 return (0); 2213 } 2214 2215 /* first scan our inuse array */ 2216 for (i = RAY_CCS_CMD_FIRST; i <= RAY_CCS_CMD_LAST; i++) { 2217 /* XXX wonder if we have to probe here to make the card go */ 2218 (void)SRAM_READ_FIELD_1(sc, RAY_GET_CCS(i), ray_cmd, c_status); 2219 if (!sc->sc_ccsinuse[i]) 2220 break; 2221 } 2222 if (i > RAY_CCS_CMD_LAST) { 2223 if (track) 2224 ray_cmd_schedule(sc, track); 2225 return (0); 2226 } 2227 sc->sc_ccsinuse[i] = 1; 2228 ccs = RAY_GET_CCS(i); 2229 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status, RAY_CCS_STATUS_BUSY); 2230 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_cmd, cmd); 2231 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_link, RAY_CCS_LINK_NULL); 2232 2233 *ccsp = ccs; 2234 return (1); 2235 } 2236 2237 2238 /* 2239 * this function sets the pending bit for the command given in 'need' 2240 * and schedules a timeout if none is scheduled already. Any command 2241 * that uses the `host to ecf' region must be serialized. 2242 */ 2243 static void 2244 ray_set_pending(sc, cmdf) 2245 struct ray_softc *sc; 2246 u_int cmdf; 2247 { 2248 RAY_DPRINTF(("%s: ray_set_pending 0x%x\n", sc->sc_xname, cmdf)); 2249 2250 sc->sc_scheduled |= cmdf; 2251 if (!sc->sc_timoneed) { 2252 RAY_DPRINTF(("%s: ray_set_pending new timo\n", sc->sc_xname)); 2253 callout_reset(&sc->sc_check_scheduled_ch, 2254 RAY_CHECK_SCHED_TIMEOUT, ray_check_scheduled, sc); 2255 sc->sc_timoneed = 1; 2256 } 2257 } 2258 2259 /* 2260 * schedule the `cmdf' for completion later 2261 */ 2262 static void 2263 ray_cmd_schedule(sc, cmdf) 2264 struct ray_softc *sc; 2265 int cmdf; 2266 { 2267 int track; 2268 2269 RAY_DPRINTF(("%s: ray_cmd_schedule 0x%x\n", sc->sc_xname, cmdf)); 2270 2271 track = cmdf; 2272 if ((cmdf & SCP_UPD_MASK) == 0) 2273 ray_set_pending(sc, track); 2274 else if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) { 2275 /* don't do timeout mechaniscm if subcmd already going */ 2276 sc->sc_scheduled |= cmdf; 2277 } else 2278 ray_set_pending(sc, cmdf | SCP_UPDATESUBCMD); 2279 } 2280 2281 /* 2282 * check to see if `cmdf' has been scheduled 2283 */ 2284 static int 2285 ray_cmd_is_scheduled(sc, cmdf) 2286 struct ray_softc *sc; 2287 int cmdf; 2288 { 2289 RAY_DPRINTF(("%s: ray_cmd_is_scheduled 0x%x\n", sc->sc_xname, cmdf)); 2290 2291 return ((sc->sc_scheduled & cmdf) ? 1 : 0); 2292 } 2293 2294 /* 2295 * cancel a scheduled command (not a running one though!) 2296 */ 2297 static void 2298 ray_cmd_cancel(sc, cmdf) 2299 struct ray_softc *sc; 2300 int cmdf; 2301 { 2302 RAY_DPRINTF(("%s: ray_cmd_cancel 0x%x\n", sc->sc_xname, cmdf)); 2303 2304 sc->sc_scheduled &= ~cmdf; 2305 if ((cmdf & SCP_UPD_MASK) && (sc->sc_scheduled & SCP_UPD_MASK) == 0) 2306 sc->sc_scheduled &= ~SCP_UPDATESUBCMD; 2307 2308 /* if nothing else needed cancel the timer */ 2309 if (sc->sc_scheduled == 0 && sc->sc_timoneed) { 2310 callout_stop(&sc->sc_check_scheduled_ch); 2311 sc->sc_timoneed = 0; 2312 } 2313 } 2314 2315 /* 2316 * called to indicate the 'cmdf' has been issued 2317 */ 2318 static void 2319 ray_cmd_ran(sc, cmdf) 2320 struct ray_softc *sc; 2321 int cmdf; 2322 { 2323 RAY_DPRINTF(("%s: ray_cmd_ran 0x%x\n", sc->sc_xname, cmdf)); 2324 2325 if (cmdf & SCP_UPD_MASK) 2326 sc->sc_running |= cmdf | SCP_UPDATESUBCMD; 2327 else 2328 sc->sc_running |= cmdf; 2329 2330 if ((cmdf & SCP_TIMOCHECK_CMD_MASK) && !sc->sc_timocheck) { 2331 callout_reset(&sc->sc_check_ccs_ch, RAY_CHECK_CCS_TIMEOUT, 2332 ray_check_ccs, sc); 2333 sc->sc_timocheck = 1; 2334 } 2335 } 2336 2337 /* 2338 * check to see if `cmdf' has been issued 2339 */ 2340 static int 2341 ray_cmd_is_running(sc, cmdf) 2342 struct ray_softc *sc; 2343 int cmdf; 2344 { 2345 RAY_DPRINTF(("%s: ray_cmd_is_running 0x%x\n", sc->sc_xname, cmdf)); 2346 2347 return ((sc->sc_running & cmdf) ? 1 : 0); 2348 } 2349 2350 /* 2351 * the given `cmdf' that was issued has completed 2352 */ 2353 static void 2354 ray_cmd_done(sc, cmdf) 2355 struct ray_softc *sc; 2356 int cmdf; 2357 { 2358 RAY_DPRINTF(("%s: ray_cmd_done 0x%x\n", sc->sc_xname, cmdf)); 2359 2360 sc->sc_running &= ~cmdf; 2361 if (cmdf & SCP_UPD_MASK) { 2362 sc->sc_running &= ~SCP_UPDATESUBCMD; 2363 if (sc->sc_scheduled & SCP_UPD_MASK) 2364 ray_cmd_schedule(sc, sc->sc_scheduled & SCP_UPD_MASK); 2365 } 2366 if ((sc->sc_running & SCP_TIMOCHECK_CMD_MASK) == 0 && sc->sc_timocheck){ 2367 callout_stop(&sc->sc_check_ccs_ch); 2368 sc->sc_timocheck = 0; 2369 } 2370 } 2371 2372 /* 2373 * issue the command 2374 * only used for commands not tx 2375 */ 2376 static int 2377 ray_issue_cmd(sc, ccs, track) 2378 struct ray_softc *sc; 2379 bus_size_t ccs; 2380 u_int track; 2381 { 2382 u_int i; 2383 2384 RAY_DPRINTF(("%s: ray_cmd_issue 0x%x\n", sc->sc_xname, track)); 2385 2386 /* 2387 * XXX other drivers did this, but I think 2388 * what we really want to do is just make sure we don't 2389 * get here or that spinning is ok 2390 */ 2391 i = 0; 2392 while (!RAY_ECF_READY(sc)) 2393 if (++i > 50) { 2394 ray_free_ccs(sc, ccs); 2395 if (track) 2396 ray_cmd_schedule(sc, track); 2397 return (0); 2398 } 2399 2400 SRAM_WRITE_1(sc, RAY_SCB_CCSI, RAY_GET_INDEX(ccs)); 2401 RAY_ECF_START_CMD(sc); 2402 ray_cmd_ran(sc, track); 2403 2404 return (1); 2405 } 2406 2407 /* 2408 * send a simple command if we can 2409 */ 2410 static int 2411 ray_simple_cmd(sc, cmd, track) 2412 struct ray_softc *sc; 2413 u_int cmd, track; 2414 { 2415 bus_size_t ccs; 2416 2417 return (ray_alloc_ccs(sc, &ccs, cmd, track) && 2418 ray_issue_cmd(sc, ccs, track)); 2419 } 2420 2421 /* 2422 * Functions based on CCS commands 2423 */ 2424 2425 /* 2426 * run a update subcommand 2427 */ 2428 static void 2429 ray_update_subcmd(sc) 2430 struct ray_softc *sc; 2431 { 2432 int submask, i; 2433 2434 RAY_DPRINTF(("%s: ray_update_subcmd\n", sc->sc_xname)); 2435 2436 ray_cmd_cancel(sc, SCP_UPDATESUBCMD); 2437 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 2438 return; 2439 submask = SCP_UPD_FIRST; 2440 for (i = 0; i < ray_nsubcmdtab; submask <<= 1, i++) { 2441 if ((sc->sc_scheduled & SCP_UPD_MASK) == 0) 2442 break; 2443 /* when done the next command will be scheduled */ 2444 if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) 2445 break; 2446 if (!RAY_ECF_READY(sc)) 2447 break; 2448 /* 2449 * give priority to LSB -- e.g., if previous loop reschuled 2450 * doing this command after calling the function won't catch 2451 * if a later command sets an earlier bit 2452 */ 2453 if (sc->sc_scheduled & ((submask - 1) & SCP_UPD_MASK)) 2454 break; 2455 if (sc->sc_scheduled & submask) 2456 (*ray_subcmdtab[i])(sc); 2457 } 2458 } 2459 2460 /* 2461 * report a parameter 2462 */ 2463 static void 2464 ray_report_params(sc) 2465 struct ray_softc *sc; 2466 { 2467 bus_size_t ccs; 2468 2469 ray_cmd_cancel(sc, SCP_REPORTPARAMS); 2470 2471 if (!sc->sc_repreq) 2472 return; 2473 2474 /* do the issue check before equality check */ 2475 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 2476 return; 2477 else if (ray_cmd_is_running(sc, SCP_REPORTPARAMS)) { 2478 ray_cmd_schedule(sc, SCP_REPORTPARAMS); 2479 return; 2480 } else if (!ray_alloc_ccs(sc, &ccs, RAY_CMD_REPORT_PARAMS, 2481 SCP_REPORTPARAMS)) 2482 return; 2483 2484 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_report, c_paramid, 2485 sc->sc_repreq->r_paramid); 2486 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_report, c_nparam, 1); 2487 (void)ray_issue_cmd(sc, ccs, SCP_REPORTPARAMS); 2488 } 2489 2490 /* 2491 * start an association 2492 */ 2493 static void 2494 ray_start_assoc(sc) 2495 struct ray_softc *sc; 2496 { 2497 ray_cmd_cancel(sc, SCP_STARTASSOC); 2498 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 2499 return; 2500 else if (ray_cmd_is_running(sc, SCP_STARTASSOC)) 2501 return; 2502 (void)ray_simple_cmd(sc, RAY_CMD_START_ASSOC, SCP_STARTASSOC); 2503 } 2504 2505 /* 2506 * Subcommand functions that use the SCP_UPDATESUBCMD command 2507 * (and are serialized with respect to other update sub commands 2508 */ 2509 2510 /* 2511 * download the startup parameters to the card 2512 * -- no outstanding commands expected 2513 */ 2514 static void 2515 ray_download_params(sc) 2516 struct ray_softc *sc; 2517 { 2518 struct ray_startup_params_head *sp; 2519 struct ray_startup_params_tail_5 *sp5; 2520 struct ray_startup_params_tail_4 *sp4; 2521 bus_size_t off; 2522 2523 RAY_DPRINTF(("%s: init_startup_params\n", sc->sc_xname)); 2524 2525 ray_cmd_cancel(sc, SCP_UPD_STARTUP); 2526 2527 #define PUT2(p, v) \ 2528 do { (p)[0] = ((v >> 8) & 0xff); (p)[1] = (v & 0xff); } while(0) 2529 2530 sp = &sc->sc_startup; 2531 sp4 = &sc->sc_startup_4; 2532 sp5 = &sc->sc_startup_5; 2533 memset(sp, 0, sizeof(*sp)); 2534 if (sc->sc_version == SC_BUILD_4) 2535 memset(sp4, 0, sizeof(*sp4)); 2536 else 2537 memset(sp5, 0, sizeof(*sp5)); 2538 /* XXX: Raylink firmware doesn't have length field for ssid */ 2539 memcpy(sp->sp_ssid, sc->sc_dnwid.i_nwid, sizeof(sp->sp_ssid)); 2540 sp->sp_scan_mode = 0x1; 2541 memcpy(sp->sp_mac_addr, sc->sc_ecf_startup.e_station_addr, 2542 ETHER_ADDR_LEN); 2543 PUT2(sp->sp_frag_thresh, 0x7fff); /* disabled */ 2544 if (sc->sc_version == SC_BUILD_4) { 2545 #if 1 2546 /* linux/fbsd */ 2547 PUT2(sp->sp_dwell_time, 0x200); 2548 PUT2(sp->sp_beacon_period, 1); 2549 #else 2550 /* divined */ 2551 PUT2(sp->sp_dwell_time, 0x400); 2552 PUT2(sp->sp_beacon_period, 0); 2553 #endif 2554 } else { 2555 PUT2(sp->sp_dwell_time, 128); 2556 PUT2(sp->sp_beacon_period, 256); 2557 } 2558 sp->sp_dtim_interval = 1; 2559 #if 0 2560 /* these are the documented defaults for build 5/6 */ 2561 sp->sp_max_retry = 0x1f; 2562 sp->sp_ack_timo = 0x86; 2563 sp->sp_sifs = 0x1c; 2564 #elif 1 2565 /* these were scrounged from the linux driver */ 2566 sp->sp_max_retry = 0x07; 2567 2568 sp->sp_ack_timo = 0xa3; 2569 sp->sp_sifs = 0x1d; 2570 #else 2571 /* these were divined */ 2572 sp->sp_max_retry = 0x03; 2573 2574 sp->sp_ack_timo = 0xa3; 2575 sp->sp_sifs = 0x1d; 2576 #endif 2577 #if 0 2578 /* these are the documented defaults for build 5/6 */ 2579 sp->sp_difs = 0x82; 2580 sp->sp_pifs = 0; 2581 #else 2582 /* linux/fbsd */ 2583 sp->sp_difs = 0x82; 2584 2585 if (sc->sc_version == SC_BUILD_4) 2586 sp->sp_pifs = 0xce; 2587 else 2588 sp->sp_pifs = 0x4e; 2589 #endif 2590 2591 PUT2(sp->sp_rts_thresh, 0x7fff); /* disabled */ 2592 if (sc->sc_version == SC_BUILD_4) { 2593 PUT2(sp->sp_scan_dwell, 0xfb1e); 2594 PUT2(sp->sp_scan_max_dwell, 0xc75c); 2595 } else { 2596 PUT2(sp->sp_scan_dwell, 0x4e2); 2597 PUT2(sp->sp_scan_max_dwell, 0x38a4); 2598 } 2599 sp->sp_assoc_timo = 0x5; 2600 if (sc->sc_version == SC_BUILD_4) { 2601 #if 0 2602 /* linux/fbsd */ 2603 sp->sp_adhoc_scan_cycle = 0x4; 2604 sp->sp_infra_scan_cycle = 0x2; 2605 sp->sp_infra_super_scan_cycle = 0x4; 2606 #else 2607 /* divined */ 2608 sp->sp_adhoc_scan_cycle = 0x8; 2609 sp->sp_infra_scan_cycle = 0x1; 2610 sp->sp_infra_super_scan_cycle = 0x18; 2611 #endif 2612 } else { 2613 sp->sp_adhoc_scan_cycle = 0x8; 2614 sp->sp_infra_scan_cycle = 0x2; 2615 sp->sp_infra_super_scan_cycle = 0x8; 2616 } 2617 sp->sp_promisc = sc->sc_promisc; 2618 PUT2(sp->sp_uniq_word, 0x0cbd); 2619 if (sc->sc_version == SC_BUILD_4) { 2620 /* XXX whats this value anyway.. the std says 50us */ 2621 /* XXX sp->sp_slot_time = 0x4e; */ 2622 sp->sp_slot_time = 0x4e; 2623 #if 1 2624 /*linux/fbsd*/ 2625 sp->sp_roam_low_snr_thresh = 0xff; 2626 #else 2627 /*divined*/ 2628 sp->sp_roam_low_snr_thresh = 0x30; 2629 #endif 2630 } else { 2631 sp->sp_slot_time = 0x32; 2632 sp->sp_roam_low_snr_thresh = 0xff; /* disabled */ 2633 } 2634 #if 1 2635 sp->sp_low_snr_count = 0xff; /* disabled */ 2636 #else 2637 /* divined -- check */ 2638 sp->sp_low_snr_count = 0x07; /* disabled */ 2639 #endif 2640 #if 0 2641 sp->sp_infra_missed_beacon_count = 0x2; 2642 #elif 1 2643 /* linux/fbsd */ 2644 sp->sp_infra_missed_beacon_count = 0x5; 2645 #else 2646 /* divined -- check, looks fishy */ 2647 sp->sp_infra_missed_beacon_count = 0x7; 2648 #endif 2649 sp->sp_adhoc_missed_beacon_count = 0xff; 2650 sp->sp_country_code = sc->sc_dcountrycode; 2651 sp->sp_hop_seq = 0x0b; 2652 if (sc->sc_version == SC_BUILD_4) { 2653 sp->sp_hop_seq_len = 0x4e; 2654 sp4->sp_cw_max = 0x3f; /* single byte on build 4 */ 2655 sp4->sp_cw_min = 0x0f; /* single byte on build 4 */ 2656 sp4->sp_noise_filter_gain = 0x4; 2657 sp4->sp_noise_limit_offset = 0x8; 2658 sp4->sp_rssi_thresh_offset = 0x28; 2659 sp4->sp_busy_thresh_offset = 0x28; 2660 sp4->sp_sync_thresh = 0x07; 2661 sp4->sp_test_mode = 0x0; 2662 sp4->sp_test_min_chan = 0x2; 2663 sp4->sp_test_max_chan = 0x2; 2664 } else { 2665 sp->sp_hop_seq_len = 0x4f; 2666 PUT2(sp5->sp_cw_max, 0x3f); 2667 PUT2(sp5->sp_cw_min, 0x0f); 2668 sp5->sp_noise_filter_gain = 0x4; 2669 sp5->sp_noise_limit_offset = 0x8; 2670 sp5->sp_rssi_thresh_offset = 0x28; 2671 sp5->sp_busy_thresh_offset = 0x28; 2672 sp5->sp_sync_thresh = 0x07; 2673 sp5->sp_test_mode = 0x0; 2674 sp5->sp_test_min_chan = 0x2; 2675 sp5->sp_test_max_chan = 0x2; 2676 #if 0 2677 sp5->sp_allow_probe_resp = 0x1; 2678 #else 2679 sp5->sp_allow_probe_resp = 0x0; 2680 #endif 2681 sp5->sp_privacy_must_start = 0x0; 2682 sp5->sp_privacy_can_join = 0x0; 2683 sp5->sp_basic_rate_set[0] = 0x2; 2684 /* 2 = 1Mbps, 3 = old 2Mbps 4 = 2Mbps */ 2685 } 2686 2687 /* we shouldn't be called with some command pending */ 2688 if (!RAY_ECF_READY(sc)) 2689 panic("ray_download_params busy"); 2690 2691 /* write the compatible part */ 2692 off = RAY_HOST_TO_ECF_BASE; 2693 ray_write_region(sc, off, sp, sizeof(sc->sc_startup)); 2694 off += sizeof(sc->sc_startup); 2695 if (sc->sc_version == SC_BUILD_4) 2696 ray_write_region(sc, off, sp4, sizeof(*sp4)); 2697 else 2698 ray_write_region(sc, off, sp5, sizeof(*sp5)); 2699 if (!ray_simple_cmd(sc, RAY_CMD_START_PARAMS, SCP_UPD_STARTUP)) 2700 panic("ray_download_params issue"); 2701 } 2702 2703 /* 2704 * start or join a network 2705 */ 2706 static void 2707 ray_start_join_net(sc) 2708 struct ray_softc *sc; 2709 { 2710 struct ray_net_params np; 2711 bus_size_t ccs; 2712 int cmd; 2713 2714 ray_cmd_cancel(sc, SCP_UPD_STARTJOIN); 2715 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 2716 return; 2717 2718 /* XXX check we may not want to re-issue */ 2719 if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) { 2720 ray_cmd_schedule(sc, SCP_UPD_STARTJOIN); 2721 return; 2722 } 2723 2724 if (sc->sc_mode == SC_MODE_ADHOC) 2725 cmd = RAY_CMD_START_NET; 2726 else 2727 cmd = RAY_CMD_JOIN_NET; 2728 2729 if (!ray_alloc_ccs(sc, &ccs, cmd, SCP_UPD_STARTJOIN)) 2730 return; 2731 sc->sc_startccs = ccs; 2732 sc->sc_startcmd = cmd; 2733 if (!memcmp(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid)) 2734 && sc->sc_omode == sc->sc_mode) 2735 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_net, c_upd_param, 0); 2736 else { 2737 sc->sc_havenet = 0; 2738 memset(&np, 0, sizeof(np)); 2739 np.p_net_type = sc->sc_mode; 2740 memcpy(np.p_ssid, sc->sc_dnwid.i_nwid, sizeof(np.p_ssid)); 2741 ray_write_region(sc, RAY_HOST_TO_ECF_BASE, &np, sizeof(np)); 2742 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_net, c_upd_param, 1); 2743 } 2744 if (ray_issue_cmd(sc, ccs, SCP_UPD_STARTJOIN)) 2745 callout_reset(&sc->sc_start_join_timo_ch, RAY_START_TIMEOUT, 2746 ray_start_join_timo, sc); 2747 } 2748 2749 static void 2750 ray_start_join_timo(arg) 2751 void *arg; 2752 { 2753 struct ray_softc *sc; 2754 u_int stat; 2755 2756 sc = arg; 2757 stat = SRAM_READ_FIELD_1(sc, sc->sc_startccs, ray_cmd, c_status); 2758 ray_start_join_net_done(sc, sc->sc_startcmd, sc->sc_startccs, stat); 2759 } 2760 2761 /* 2762 * The start/join has completed. Note: we timeout the start 2763 * command because it seems to fail to work at least on the 2764 * build 4 firmware without reporting an error. This actually 2765 * may be a result of not putting the correct params in the 2766 * initial download. If this is a timeout `stat' will be 2767 * marked busy. 2768 */ 2769 static ray_cmd_func_t 2770 ray_start_join_net_done(sc, cmd, ccs, stat) 2771 struct ray_softc *sc; 2772 u_int cmd; 2773 bus_size_t ccs; 2774 u_int stat; 2775 { 2776 int i; 2777 struct ray_net_params np; 2778 2779 callout_stop(&sc->sc_start_join_timo_ch); 2780 ray_cmd_done(sc, SCP_UPD_STARTJOIN); 2781 2782 if (stat == RAY_CCS_STATUS_FAIL) { 2783 /* XXX poke ifmedia when it supports this */ 2784 sc->sc_havenet = 0; 2785 return (ray_start_join_net); 2786 } 2787 if (stat == RAY_CCS_STATUS_BUSY || stat == RAY_CCS_STATUS_FREE) { 2788 /* handle the timeout condition */ 2789 callout_reset(&sc->sc_start_join_timo_ch, RAY_START_TIMEOUT, 2790 ray_start_join_timo, sc); 2791 2792 /* be safe -- not a lot occurs with no net though */ 2793 if (!RAY_ECF_READY(sc)) 2794 return (0); 2795 2796 /* see if our nwid is up to date */ 2797 if (!memcmp(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid)) 2798 && sc->sc_omode == sc->sc_mode) 2799 SRAM_WRITE_FIELD_1(sc,ccs, ray_cmd_net, c_upd_param, 0); 2800 else { 2801 memset(&np, 0, sizeof(np)); 2802 np.p_net_type = sc->sc_mode; 2803 memcpy(np.p_ssid, sc->sc_dnwid.i_nwid, 2804 sizeof(np.p_ssid)); 2805 ray_write_region(sc, RAY_HOST_TO_ECF_BASE, &np, 2806 sizeof(np)); 2807 SRAM_WRITE_FIELD_1(sc,ccs, ray_cmd_net, c_upd_param, 1); 2808 } 2809 2810 if (sc->sc_mode == SC_MODE_ADHOC) 2811 cmd = RAY_CMD_START_NET; 2812 else 2813 cmd = RAY_CMD_JOIN_NET; 2814 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_net, c_cmd, 2815 RAY_CCS_STATUS_BUSY); 2816 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_net, c_status, 2817 RAY_CCS_STATUS_BUSY); 2818 2819 /* we simply poke the card again issuing the same ccs */ 2820 SRAM_WRITE_1(sc, RAY_SCB_CCSI, RAY_GET_INDEX(ccs)); 2821 RAY_ECF_START_CMD(sc); 2822 ray_cmd_ran(sc, SCP_UPD_STARTJOIN); 2823 return (0); 2824 } 2825 /* get the current ssid */ 2826 SRAM_READ_FIELD_N(sc, ccs, ray_cmd_net, c_bss_id, sc->sc_bssid, 2827 sizeof(sc->sc_bssid)); 2828 2829 sc->sc_deftxrate = SRAM_READ_FIELD_1(sc, ccs, ray_cmd_net,c_def_txrate); 2830 sc->sc_encrypt = SRAM_READ_FIELD_1(sc, ccs, ray_cmd_net, c_encrypt); 2831 2832 /* adjust values for buggy build 4 */ 2833 if (sc->sc_deftxrate == 0x55) 2834 sc->sc_deftxrate = RAY_PID_BASIC_RATE_1500K; 2835 if (sc->sc_encrypt == 0x55) 2836 sc->sc_encrypt = 0; 2837 2838 if (SRAM_READ_FIELD_1(sc, ccs, ray_cmd_net, c_upd_param)) { 2839 ray_read_region(sc, RAY_HOST_TO_ECF_BASE, &np, sizeof(np)); 2840 /* XXX: Raylink firmware doesn't have length field for ssid */ 2841 for (i = 0; i < sizeof(np.p_ssid); i++) { 2842 if (np.p_ssid[i] == '\0') 2843 break; 2844 } 2845 sc->sc_cnwid.i_len = i; 2846 memcpy(sc->sc_cnwid.i_nwid, np.p_ssid, sizeof(sc->sc_cnwid)); 2847 sc->sc_omode = sc->sc_mode; 2848 if (np.p_net_type != sc->sc_mode) 2849 return (ray_start_join_net); 2850 } 2851 RAY_DPRINTF(("%s: net start/join nwid %.32s bssid %s inited %d\n", 2852 sc->sc_xname, sc->sc_cnwid.i_nwid, ether_sprintf(sc->sc_bssid), 2853 SRAM_READ_FIELD_1(sc, ccs, ray_cmd_net, c_inited))); 2854 2855 /* network is now active */ 2856 ray_cmd_schedule(sc, SCP_UPD_MCAST|SCP_UPD_PROMISC); 2857 if (cmd == RAY_CMD_JOIN_NET) 2858 return (ray_start_assoc); 2859 else { 2860 sc->sc_havenet = 1; 2861 return (ray_intr_start); 2862 } 2863 } 2864 2865 /* 2866 * set the card in/out of promiscuous mode 2867 */ 2868 static void 2869 ray_update_promisc(sc) 2870 struct ray_softc *sc; 2871 { 2872 bus_size_t ccs; 2873 int promisc; 2874 2875 ray_cmd_cancel(sc, SCP_UPD_PROMISC); 2876 2877 /* do the issue check before equality check */ 2878 if (sc->sc_if.if_flags & IFF_ALLMULTI) 2879 sc->sc_if.if_flags |= IFF_PROMISC; 2880 else if (sc->sc_if.if_pcount == 0) 2881 sc->sc_if.if_flags &= ~IFF_PROMISC; 2882 promisc = !!(sc->sc_if.if_flags & IFF_PROMISC); 2883 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 2884 return; 2885 else if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) { 2886 ray_cmd_schedule(sc, SCP_UPD_PROMISC); 2887 return; 2888 } else if (promisc == sc->sc_promisc) 2889 return; 2890 else if (!ray_alloc_ccs(sc,&ccs,RAY_CMD_UPDATE_PARAMS, SCP_UPD_PROMISC)) 2891 return; 2892 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update, c_paramid, RAY_PID_PROMISC); 2893 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update, c_nparam, 1); 2894 SRAM_WRITE_1(sc, RAY_HOST_TO_ECF_BASE, promisc); 2895 (void)ray_issue_cmd(sc, ccs, SCP_UPD_PROMISC); 2896 } 2897 2898 /* 2899 * update the parameter based on what the user passed in 2900 */ 2901 static void 2902 ray_update_params(sc) 2903 struct ray_softc *sc; 2904 { 2905 bus_size_t ccs; 2906 2907 ray_cmd_cancel(sc, SCP_UPD_UPDATEPARAMS); 2908 if (!sc->sc_updreq) { 2909 /* XXX do we need to wakeup here? */ 2910 return; 2911 } 2912 2913 /* do the issue check before equality check */ 2914 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 2915 return; 2916 else if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) { 2917 ray_cmd_schedule(sc, SCP_UPD_UPDATEPARAMS); 2918 return; 2919 } else if (!ray_alloc_ccs(sc, &ccs, RAY_CMD_UPDATE_PARAMS, 2920 SCP_UPD_UPDATEPARAMS)) 2921 return; 2922 2923 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update, c_paramid, 2924 sc->sc_updreq->r_paramid); 2925 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update, c_nparam, 1); 2926 ray_write_region(sc, RAY_HOST_TO_ECF_BASE, sc->sc_updreq->r_data, 2927 sc->sc_updreq->r_len); 2928 2929 (void)ray_issue_cmd(sc, ccs, SCP_UPD_UPDATEPARAMS); 2930 } 2931 2932 /* 2933 * set the multicast filter list 2934 */ 2935 static void 2936 ray_update_mcast(sc) 2937 struct ray_softc *sc; 2938 { 2939 bus_size_t ccs; 2940 struct ether_multistep step; 2941 struct ether_multi *enm; 2942 struct ethercom *ec; 2943 bus_size_t bufp; 2944 int count; 2945 2946 ec = &sc->sc_ec; 2947 ray_cmd_cancel(sc, SCP_UPD_MCAST); 2948 2949 /* see if we have any ranges */ 2950 if ((count = sc->sc_ec.ec_multicnt) < 17) { 2951 ETHER_FIRST_MULTI(step, ec, enm); 2952 while (enm) { 2953 /* see if this is a range */ 2954 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 2955 ETHER_ADDR_LEN)) { 2956 count = 17; 2957 break; 2958 } 2959 ETHER_NEXT_MULTI(step, enm); 2960 } 2961 } 2962 2963 /* track this stuff even when not running */ 2964 if (count > 16) { 2965 sc->sc_if.if_flags |= IFF_ALLMULTI; 2966 ray_update_promisc(sc); 2967 return; 2968 } else if (sc->sc_if.if_flags & IFF_ALLMULTI) { 2969 sc->sc_if.if_flags &= ~IFF_ALLMULTI; 2970 ray_update_promisc(sc); 2971 } 2972 2973 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 2974 return; 2975 else if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) { 2976 ray_cmd_schedule(sc, SCP_UPD_MCAST); 2977 return; 2978 } else if (!ray_alloc_ccs(sc,&ccs, RAY_CMD_UPDATE_MCAST, SCP_UPD_MCAST)) 2979 return; 2980 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update_mcast, c_nmcast, count); 2981 bufp = RAY_HOST_TO_ECF_BASE; 2982 ETHER_FIRST_MULTI(step, ec, enm); 2983 while (enm) { 2984 ray_write_region(sc, bufp, enm->enm_addrlo, ETHER_ADDR_LEN); 2985 bufp += ETHER_ADDR_LEN; 2986 ETHER_NEXT_MULTI(step, enm); 2987 } 2988 (void)ray_issue_cmd(sc, ccs, SCP_UPD_MCAST); 2989 } 2990 2991 /* 2992 * User issued commands 2993 */ 2994 2995 /* 2996 * issue a update params 2997 * 2998 * expected to be called in sleapable context -- intended for user stuff 2999 */ 3000 static int 3001 ray_user_update_params(sc, pr) 3002 struct ray_softc *sc; 3003 struct ray_param_req *pr; 3004 { 3005 int rv; 3006 3007 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) { 3008 pr->r_failcause = RAY_FAILCAUSE_EDEVSTOP; 3009 return (EIO); 3010 } 3011 3012 /* wait to be able to issue the command */ 3013 rv = 0; 3014 while (ray_cmd_is_running(sc, SCP_UPD_UPDATEPARAMS) || 3015 ray_cmd_is_scheduled(sc, SCP_UPD_UPDATEPARAMS)) { 3016 rv = tsleep(ray_update_params, 0|PCATCH, "cmd in use", 0); 3017 if (rv) 3018 return (rv); 3019 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) { 3020 pr->r_failcause = RAY_FAILCAUSE_EDEVSTOP; 3021 return (EIO); 3022 } 3023 } 3024 3025 pr->r_failcause = RAY_FAILCAUSE_WAITING; 3026 sc->sc_updreq = pr; 3027 ray_cmd_schedule(sc, SCP_UPD_UPDATEPARAMS); 3028 ray_check_scheduled(sc); 3029 3030 while (pr->r_failcause == RAY_FAILCAUSE_WAITING) 3031 (void)tsleep(ray_update_params, 0, "waiting cmd", 0); 3032 wakeup(ray_update_params); 3033 3034 return (0); 3035 } 3036 3037 /* 3038 * issue a report params 3039 * 3040 * expected to be called in sleapable context -- intended for user stuff 3041 */ 3042 static int 3043 ray_user_report_params(sc, pr) 3044 struct ray_softc *sc; 3045 struct ray_param_req *pr; 3046 { 3047 int rv; 3048 3049 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) { 3050 pr->r_failcause = RAY_FAILCAUSE_EDEVSTOP; 3051 return (EIO); 3052 } 3053 3054 /* wait to be able to issue the command */ 3055 rv = 0; 3056 while (ray_cmd_is_running(sc, SCP_REPORTPARAMS) 3057 || ray_cmd_is_scheduled(sc, SCP_REPORTPARAMS)) { 3058 rv = tsleep(ray_report_params, 0|PCATCH, "cmd in use", 0); 3059 if (rv) 3060 return (rv); 3061 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) { 3062 pr->r_failcause = RAY_FAILCAUSE_EDEVSTOP; 3063 return (EIO); 3064 } 3065 } 3066 3067 pr->r_failcause = RAY_FAILCAUSE_WAITING; 3068 sc->sc_repreq = pr; 3069 ray_cmd_schedule(sc, SCP_REPORTPARAMS); 3070 ray_check_scheduled(sc); 3071 3072 while (pr->r_failcause == RAY_FAILCAUSE_WAITING) 3073 (void)tsleep(ray_report_params, 0, "waiting cmd", 0); 3074 wakeup(ray_report_params); 3075 3076 return (0); 3077 } 3078 3079 3080 /* 3081 * this is a temporary wrapper around bus_space_read_region_1 3082 * as it seems to mess with gcc. the line numbers get offset 3083 * presumably this is related to the inline asm on i386. 3084 */ 3085 3086 static void 3087 ray_read_region(sc, off, vp, c) 3088 struct ray_softc *sc; 3089 bus_size_t off; 3090 void *vp; 3091 size_t c; 3092 { 3093 #ifdef RAY_USE_OPTIMIZED_COPY 3094 u_int n2, n4, tmp; 3095 u_int8_t *p; 3096 3097 p = vp; 3098 3099 /* XXX we may be making poor assumptions here but lets hope */ 3100 switch ((off|(bus_addr_t)p) & 0x03) { 3101 case 0: 3102 if ((n4 = c / 4)) { 3103 bus_space_read_region_4(sc->sc_memt, sc->sc_memh, off, 3104 p, n4); 3105 tmp = c & ~0x3; 3106 c &= 0x3; 3107 p += tmp; 3108 off += tmp; 3109 } 3110 switch (c) { 3111 case 3: 3112 *p = bus_space_read_1(sc->sc_memt,sc->sc_memh, off); 3113 p++, off++; 3114 case 2: 3115 *p = bus_space_read_1(sc->sc_memt,sc->sc_memh, off); 3116 p++, off++; 3117 case 1: 3118 *p = bus_space_read_1(sc->sc_memt,sc->sc_memh, off); 3119 } 3120 break; 3121 case 2: 3122 if ((n2 = (c >> 1))) 3123 bus_space_read_region_2(sc->sc_memt, sc->sc_memh, off, 3124 p, n2); 3125 if (c & 1) { 3126 c &= ~0x1; 3127 *(p + c) = bus_space_read_1(sc->sc_memt, sc->sc_memh, 3128 off + c); 3129 } 3130 break; 3131 case 1: 3132 case 3: 3133 bus_space_read_region_1(sc->sc_memt, sc->sc_memh, off, p, c); 3134 break; 3135 } 3136 #else 3137 bus_space_read_region_1(sc->sc_memt, sc->sc_memh, off, vp, c); 3138 #endif 3139 } 3140 3141 /* 3142 * this is a temporary wrapper around bus_space_write_region_1 3143 * as it seems to mess with gcc. the line numbers get offset 3144 * presumably this is related to the inline asm on i386. 3145 */ 3146 static void 3147 ray_write_region(sc, off, vp, c) 3148 struct ray_softc *sc; 3149 bus_size_t off; 3150 void *vp; 3151 size_t c; 3152 { 3153 #ifdef RAY_USE_OPTIMIZED_COPY 3154 size_t n2, n4, tmp; 3155 u_int8_t *p; 3156 3157 p = vp; 3158 /* XXX we may be making poor assumptions here but lets hope */ 3159 switch ((off|(bus_addr_t)p) & 0x03) { 3160 case 0: 3161 if ((n4 = (c >> 2))) { 3162 bus_space_write_region_4(sc->sc_memt, sc->sc_memh, off, 3163 p, n4); 3164 tmp = c & ~0x3; 3165 c &= 0x3; 3166 p += tmp; 3167 off += tmp; 3168 } 3169 switch (c) { 3170 case 3: 3171 bus_space_write_1(sc->sc_memt,sc->sc_memh, off, *p); 3172 p++, off++; 3173 case 2: 3174 bus_space_write_1(sc->sc_memt,sc->sc_memh, off, *p); 3175 p++, off++; 3176 case 1: 3177 bus_space_write_1(sc->sc_memt,sc->sc_memh, off, *p); 3178 } 3179 break; 3180 case 2: 3181 if ((n2 = (c >> 1))) 3182 bus_space_write_region_2(sc->sc_memt, sc->sc_memh, off, 3183 p, n2); 3184 if (c & 0x1) { 3185 c &= ~0x1; 3186 bus_space_write_1(sc->sc_memt, sc->sc_memh, 3187 off + c, *(p + c)); 3188 } 3189 break; 3190 case 1: 3191 case 3: 3192 bus_space_write_region_1(sc->sc_memt, sc->sc_memh, off, p, c); 3193 break; 3194 } 3195 #else 3196 bus_space_write_region_1(sc->sc_memt, sc->sc_memh, off, vp, c); 3197 #endif 3198 } 3199 3200 #ifdef RAY_DEBUG 3201 3202 #define PRINTABLE(c) ((c) >= 0x20 && (c) <= 0x7f) 3203 3204 void 3205 hexdump(const u_int8_t *d, int len, int br, int div, int fl) 3206 { 3207 int i, j, offw, first, tlen, ni, nj, sp; 3208 3209 sp = br / div; 3210 offw = 0; 3211 if (len && (fl & HEXDF_NOOFFSET) == 0) { 3212 tlen = len; 3213 do { 3214 offw++; 3215 } while (tlen /= br); 3216 } 3217 if (offw) 3218 printf("%0*x: ", offw, 0); 3219 for (i = 0; i < len; i++, d++) { 3220 if (i && (i % br) == 0) { 3221 if ((fl & HEXDF_NOASCII) == 0) { 3222 printf(" "); 3223 d -= br; 3224 for (j = 0; j < br; d++, j++) { 3225 if (j && (j % sp) == 0) 3226 printf(" "); 3227 if (PRINTABLE(*d)) 3228 printf("%c", (int)*d); 3229 else 3230 printf("."); 3231 } 3232 } 3233 if (offw) 3234 printf("\n%0*x: ", offw, i); 3235 else 3236 printf("\n"); 3237 if ((fl & HEXDF_NOCOMPRESS) == 0) { 3238 first = 1; 3239 while (len - i >= br) { 3240 if (memcmp(d, d - br, br)) 3241 break; 3242 d += br; 3243 i += br; 3244 if (first) { 3245 printf("*"); 3246 first = 0; 3247 } 3248 } 3249 if (len == i) { 3250 printf("\n%0*x", offw, i); 3251 return; 3252 } 3253 } 3254 } else if (i && (i % sp) == 0) 3255 printf(" "); 3256 printf("%02x ", *d); 3257 } 3258 if (len && (((i - 1) % br) || i == 1)) { 3259 if ((fl & HEXDF_NOASCII) == 0) { 3260 i = i % br ? i % br : br; 3261 ni = (br - i) % br; 3262 j = (i - 1) / sp; 3263 nj = (div - j - 1) % div; 3264 j = 3 * ni + nj + 3; 3265 printf("%*s", j, ""); 3266 d -= i; 3267 for (j = 0; j < i; d++, j++) { 3268 if (j && (j % sp) == 0) 3269 printf(" "); 3270 if (PRINTABLE(*d)) 3271 printf("%c", (int)*d); 3272 else 3273 printf("."); 3274 } 3275 } 3276 printf("\n"); 3277 } 3278 } 3279 3280 3281 3282 static void 3283 ray_dump_mbuf(sc, m) 3284 struct ray_softc *sc; 3285 struct mbuf *m; 3286 { 3287 u_int8_t *d, *ed; 3288 u_int i; 3289 3290 printf("%s: pkt dump:", sc->sc_xname); 3291 i = 0; 3292 for (; m; m = m->m_next) { 3293 d = mtod(m, u_int8_t *); 3294 ed = d + m->m_len; 3295 3296 for (; d < ed; i++, d++) { 3297 if ((i % 16) == 0) 3298 printf("\n\t"); 3299 else if ((i % 8) == 0) 3300 printf(" "); 3301 printf(" %02x", *d); 3302 } 3303 } 3304 if ((i - 1) % 16) 3305 printf("\n"); 3306 } 3307 #endif /* RAY_DEBUG */ 3308 3309 #ifdef RAY_DO_SIGLEV 3310 static void 3311 ray_update_siglev(sc, src, siglev) 3312 struct ray_softc *sc; 3313 u_int8_t *src; 3314 u_int8_t siglev; 3315 { 3316 int i, mini; 3317 struct timeval mint; 3318 struct ray_siglev *sl; 3319 3320 /* try to find host */ 3321 for (i = 0; i < RAY_NSIGLEVRECS; i++) { 3322 sl = &sc->sc_siglevs[i]; 3323 if (memcmp(sl->rsl_host, src, ETHER_ADDR_LEN) == 0) 3324 goto found; 3325 } 3326 /* not found, find oldest slot */ 3327 mini = 0; 3328 mint.tv_sec = LONG_MAX; 3329 mint.tv_usec = 0; 3330 for (i = 0; i < RAY_NSIGLEVRECS; i++) { 3331 sl = &sc->sc_siglevs[i]; 3332 if (timercmp(&sl->rsl_time, &mint, <)) { 3333 mini = i; 3334 mint = sl->rsl_time; 3335 } 3336 } 3337 sl = &sc->sc_siglevs[mini]; 3338 memset(sl->rsl_siglevs, 0, RAY_NSIGLEV); 3339 memcpy(sl->rsl_host, src, ETHER_ADDR_LEN); 3340 3341 found: 3342 microtime(&sl->rsl_time); 3343 memmove(&sl->rsl_siglevs[1], sl->rsl_siglevs, RAY_NSIGLEV-1); 3344 sl->rsl_siglevs[0] = siglev; 3345 } 3346 #endif 3347