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