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