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