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