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