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