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