1 /* 2 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr> 8 * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org> 9 * 10 * Permission to use, copy, modify, and distribute this software for any 11 * purpose with or without fee is hereby granted, provided that the above 12 * copyright notice and this permission notice appear in all copies. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23 /* 24 * Ralink Technology RT2501USB/RT2601USB chipset driver 25 * http://www.ralinktech.com.tw/ 26 */ 27 #include <sys/types.h> 28 #include <sys/cmn_err.h> 29 #include <sys/strsubr.h> 30 #include <sys/modctl.h> 31 #include <sys/devops.h> 32 #include <sys/mac_provider.h> 33 #include <sys/mac_wifi.h> 34 #include <sys/net80211.h> 35 #include <sys/byteorder.h> 36 37 #define USBDRV_MAJOR_VER 2 38 #define USBDRV_MINOR_VER 0 39 #include <sys/usb/usba.h> 40 #include <sys/usb/usba/usba_types.h> 41 42 #include "rum_reg.h" 43 #include "rum_var.h" 44 #include "rt2573_ucode.h" 45 46 static void *rum_soft_state_p = NULL; 47 48 #define RAL_TXBUF_SIZE (IEEE80211_MAX_LEN) 49 #define RAL_RXBUF_SIZE (IEEE80211_MAX_LEN) 50 51 /* quickly determine if a given rate is CCK or OFDM */ 52 #define RUM_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22) 53 #define RUM_ACK_SIZE 14 /* 10 + 4(FCS) */ 54 #define RUM_CTS_SIZE 14 /* 10 + 4(FCS) */ 55 56 #define RUM_N(a) (sizeof (a) / sizeof ((a)[0])) 57 58 /* 59 * Supported rates for 802.11a/b/g modes (in 500Kbps unit). 60 */ 61 static const struct ieee80211_rateset rum_rateset_11a = 62 { 8, { 12, 18, 24, 36, 48, 72, 96, 108 } }; 63 64 static const struct ieee80211_rateset rum_rateset_11b = 65 { 4, { 2, 4, 11, 22 } }; 66 67 static const struct ieee80211_rateset rum_rateset_11g = 68 { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } }; 69 70 static const struct { 71 uint32_t reg; 72 uint32_t val; 73 } rum_def_mac[] = { 74 { RT2573_TXRX_CSR0, 0x025fb032 }, 75 { RT2573_TXRX_CSR1, 0x9eaa9eaf }, 76 { RT2573_TXRX_CSR2, 0x8a8b8c8d }, 77 { RT2573_TXRX_CSR3, 0x00858687 }, 78 { RT2573_TXRX_CSR7, 0x2e31353b }, 79 { RT2573_TXRX_CSR8, 0x2a2a2a2c }, 80 { RT2573_TXRX_CSR15, 0x0000000f }, 81 { RT2573_MAC_CSR6, 0x00000fff }, 82 { RT2573_MAC_CSR8, 0x016c030a }, 83 { RT2573_MAC_CSR10, 0x00000718 }, 84 { RT2573_MAC_CSR12, 0x00000004 }, 85 { RT2573_MAC_CSR13, 0x00007f00 }, 86 { RT2573_SEC_CSR0, 0x00000000 }, 87 { RT2573_SEC_CSR1, 0x00000000 }, 88 { RT2573_SEC_CSR5, 0x00000000 }, 89 { RT2573_PHY_CSR1, 0x000023b0 }, 90 { RT2573_PHY_CSR5, 0x00040a06 }, 91 { RT2573_PHY_CSR6, 0x00080606 }, 92 { RT2573_PHY_CSR7, 0x00000408 }, 93 { RT2573_AIFSN_CSR, 0x00002273 }, 94 { RT2573_CWMIN_CSR, 0x00002344 }, 95 { RT2573_CWMAX_CSR, 0x000034aa } 96 }; 97 98 static const struct { 99 uint8_t reg; 100 uint8_t val; 101 } rum_def_bbp[] = { 102 { 3, 0x80 }, 103 { 15, 0x30 }, 104 { 17, 0x20 }, 105 { 21, 0xc8 }, 106 { 22, 0x38 }, 107 { 23, 0x06 }, 108 { 24, 0xfe }, 109 { 25, 0x0a }, 110 { 26, 0x0d }, 111 { 32, 0x0b }, 112 { 34, 0x12 }, 113 { 37, 0x07 }, 114 { 39, 0xf8 }, 115 { 41, 0x60 }, 116 { 53, 0x10 }, 117 { 54, 0x18 }, 118 { 60, 0x10 }, 119 { 61, 0x04 }, 120 { 62, 0x04 }, 121 { 75, 0xfe }, 122 { 86, 0xfe }, 123 { 88, 0xfe }, 124 { 90, 0x0f }, 125 { 99, 0x00 }, 126 { 102, 0x16 }, 127 { 107, 0x04 } 128 }; 129 130 static const struct rfprog { 131 uint8_t chan; 132 uint32_t r1, r2, r3, r4; 133 } rum_rf5226[] = { 134 { 1, 0x00b03, 0x001e1, 0x1a014, 0x30282 }, 135 { 2, 0x00b03, 0x001e1, 0x1a014, 0x30287 }, 136 { 3, 0x00b03, 0x001e2, 0x1a014, 0x30282 }, 137 { 4, 0x00b03, 0x001e2, 0x1a014, 0x30287 }, 138 { 5, 0x00b03, 0x001e3, 0x1a014, 0x30282 }, 139 { 6, 0x00b03, 0x001e3, 0x1a014, 0x30287 }, 140 { 7, 0x00b03, 0x001e4, 0x1a014, 0x30282 }, 141 { 8, 0x00b03, 0x001e4, 0x1a014, 0x30287 }, 142 { 9, 0x00b03, 0x001e5, 0x1a014, 0x30282 }, 143 { 10, 0x00b03, 0x001e5, 0x1a014, 0x30287 }, 144 { 11, 0x00b03, 0x001e6, 0x1a014, 0x30282 }, 145 { 12, 0x00b03, 0x001e6, 0x1a014, 0x30287 }, 146 { 13, 0x00b03, 0x001e7, 0x1a014, 0x30282 }, 147 { 14, 0x00b03, 0x001e8, 0x1a014, 0x30284 }, 148 149 { 34, 0x00b03, 0x20266, 0x36014, 0x30282 }, 150 { 38, 0x00b03, 0x20267, 0x36014, 0x30284 }, 151 { 42, 0x00b03, 0x20268, 0x36014, 0x30286 }, 152 { 46, 0x00b03, 0x20269, 0x36014, 0x30288 }, 153 154 { 36, 0x00b03, 0x00266, 0x26014, 0x30288 }, 155 { 40, 0x00b03, 0x00268, 0x26014, 0x30280 }, 156 { 44, 0x00b03, 0x00269, 0x26014, 0x30282 }, 157 { 48, 0x00b03, 0x0026a, 0x26014, 0x30284 }, 158 { 52, 0x00b03, 0x0026b, 0x26014, 0x30286 }, 159 { 56, 0x00b03, 0x0026c, 0x26014, 0x30288 }, 160 { 60, 0x00b03, 0x0026e, 0x26014, 0x30280 }, 161 { 64, 0x00b03, 0x0026f, 0x26014, 0x30282 }, 162 163 { 100, 0x00b03, 0x0028a, 0x2e014, 0x30280 }, 164 { 104, 0x00b03, 0x0028b, 0x2e014, 0x30282 }, 165 { 108, 0x00b03, 0x0028c, 0x2e014, 0x30284 }, 166 { 112, 0x00b03, 0x0028d, 0x2e014, 0x30286 }, 167 { 116, 0x00b03, 0x0028e, 0x2e014, 0x30288 }, 168 { 120, 0x00b03, 0x002a0, 0x2e014, 0x30280 }, 169 { 124, 0x00b03, 0x002a1, 0x2e014, 0x30282 }, 170 { 128, 0x00b03, 0x002a2, 0x2e014, 0x30284 }, 171 { 132, 0x00b03, 0x002a3, 0x2e014, 0x30286 }, 172 { 136, 0x00b03, 0x002a4, 0x2e014, 0x30288 }, 173 { 140, 0x00b03, 0x002a6, 0x2e014, 0x30280 }, 174 175 { 149, 0x00b03, 0x002a8, 0x2e014, 0x30287 }, 176 { 153, 0x00b03, 0x002a9, 0x2e014, 0x30289 }, 177 { 157, 0x00b03, 0x002ab, 0x2e014, 0x30281 }, 178 { 161, 0x00b03, 0x002ac, 0x2e014, 0x30283 }, 179 { 165, 0x00b03, 0x002ad, 0x2e014, 0x30285 } 180 }, rum_rf5225[] = { 181 { 1, 0x00b33, 0x011e1, 0x1a014, 0x30282 }, 182 { 2, 0x00b33, 0x011e1, 0x1a014, 0x30287 }, 183 { 3, 0x00b33, 0x011e2, 0x1a014, 0x30282 }, 184 { 4, 0x00b33, 0x011e2, 0x1a014, 0x30287 }, 185 { 5, 0x00b33, 0x011e3, 0x1a014, 0x30282 }, 186 { 6, 0x00b33, 0x011e3, 0x1a014, 0x30287 }, 187 { 7, 0x00b33, 0x011e4, 0x1a014, 0x30282 }, 188 { 8, 0x00b33, 0x011e4, 0x1a014, 0x30287 }, 189 { 9, 0x00b33, 0x011e5, 0x1a014, 0x30282 }, 190 { 10, 0x00b33, 0x011e5, 0x1a014, 0x30287 }, 191 { 11, 0x00b33, 0x011e6, 0x1a014, 0x30282 }, 192 { 12, 0x00b33, 0x011e6, 0x1a014, 0x30287 }, 193 { 13, 0x00b33, 0x011e7, 0x1a014, 0x30282 }, 194 { 14, 0x00b33, 0x011e8, 0x1a014, 0x30284 }, 195 196 { 34, 0x00b33, 0x01266, 0x26014, 0x30282 }, 197 { 38, 0x00b33, 0x01267, 0x26014, 0x30284 }, 198 { 42, 0x00b33, 0x01268, 0x26014, 0x30286 }, 199 { 46, 0x00b33, 0x01269, 0x26014, 0x30288 }, 200 201 { 36, 0x00b33, 0x01266, 0x26014, 0x30288 }, 202 { 40, 0x00b33, 0x01268, 0x26014, 0x30280 }, 203 { 44, 0x00b33, 0x01269, 0x26014, 0x30282 }, 204 { 48, 0x00b33, 0x0126a, 0x26014, 0x30284 }, 205 { 52, 0x00b33, 0x0126b, 0x26014, 0x30286 }, 206 { 56, 0x00b33, 0x0126c, 0x26014, 0x30288 }, 207 { 60, 0x00b33, 0x0126e, 0x26014, 0x30280 }, 208 { 64, 0x00b33, 0x0126f, 0x26014, 0x30282 }, 209 210 { 100, 0x00b33, 0x0128a, 0x2e014, 0x30280 }, 211 { 104, 0x00b33, 0x0128b, 0x2e014, 0x30282 }, 212 { 108, 0x00b33, 0x0128c, 0x2e014, 0x30284 }, 213 { 112, 0x00b33, 0x0128d, 0x2e014, 0x30286 }, 214 { 116, 0x00b33, 0x0128e, 0x2e014, 0x30288 }, 215 { 120, 0x00b33, 0x012a0, 0x2e014, 0x30280 }, 216 { 124, 0x00b33, 0x012a1, 0x2e014, 0x30282 }, 217 { 128, 0x00b33, 0x012a2, 0x2e014, 0x30284 }, 218 { 132, 0x00b33, 0x012a3, 0x2e014, 0x30286 }, 219 { 136, 0x00b33, 0x012a4, 0x2e014, 0x30288 }, 220 { 140, 0x00b33, 0x012a6, 0x2e014, 0x30280 }, 221 222 { 149, 0x00b33, 0x012a8, 0x2e014, 0x30287 }, 223 { 153, 0x00b33, 0x012a9, 0x2e014, 0x30289 }, 224 { 157, 0x00b33, 0x012ab, 0x2e014, 0x30281 }, 225 { 161, 0x00b33, 0x012ac, 0x2e014, 0x30283 }, 226 { 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 } 227 }; 228 229 /* 230 * device operations 231 */ 232 static int rum_attach(dev_info_t *, ddi_attach_cmd_t); 233 static int rum_detach(dev_info_t *, ddi_detach_cmd_t); 234 235 /* 236 * Module Loading Data & Entry Points 237 */ 238 DDI_DEFINE_STREAM_OPS(rum_dev_ops, nulldev, nulldev, rum_attach, 239 rum_detach, nodev, NULL, D_MP, NULL, ddi_quiesce_not_needed); 240 241 static struct modldrv rum_modldrv = { 242 &mod_driverops, /* Type of module. This one is a driver */ 243 "rum driver v1.2", /* short description */ 244 &rum_dev_ops /* driver specific ops */ 245 }; 246 247 static struct modlinkage modlinkage = { 248 MODREV_1, 249 (void *)&rum_modldrv, 250 NULL 251 }; 252 253 static int rum_m_stat(void *, uint_t, uint64_t *); 254 static int rum_m_start(void *); 255 static void rum_m_stop(void *); 256 static int rum_m_promisc(void *, boolean_t); 257 static int rum_m_multicst(void *, boolean_t, const uint8_t *); 258 static int rum_m_unicst(void *, const uint8_t *); 259 static mblk_t *rum_m_tx(void *, mblk_t *); 260 static void rum_m_ioctl(void *, queue_t *, mblk_t *); 261 static int rum_m_setprop(void *, const char *, mac_prop_id_t, 262 uint_t, const void *); 263 static int rum_m_getprop(void *, const char *, mac_prop_id_t, 264 uint_t, void *); 265 static void rum_m_propinfo(void *, const char *, mac_prop_id_t, 266 mac_prop_info_handle_t); 267 268 static mac_callbacks_t rum_m_callbacks = { 269 MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO, 270 rum_m_stat, 271 rum_m_start, 272 rum_m_stop, 273 rum_m_promisc, 274 rum_m_multicst, 275 rum_m_unicst, 276 rum_m_tx, 277 NULL, 278 rum_m_ioctl, 279 NULL, /* mc_getcapab */ 280 NULL, 281 NULL, 282 rum_m_setprop, 283 rum_m_getprop, 284 rum_m_propinfo 285 }; 286 287 static void rum_amrr_start(struct rum_softc *, struct ieee80211_node *); 288 static int rum_tx_trigger(struct rum_softc *, mblk_t *); 289 static int rum_rx_trigger(struct rum_softc *); 290 291 uint32_t rum_dbg_flags = 0; 292 293 void 294 ral_debug(uint32_t dbg_flags, const int8_t *fmt, ...) 295 { 296 va_list args; 297 298 if (dbg_flags & rum_dbg_flags) { 299 va_start(args, fmt); 300 vcmn_err(CE_CONT, fmt, args); 301 va_end(args); 302 } 303 } 304 305 static void 306 rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len) 307 { 308 usb_ctrl_setup_t req; 309 usb_cr_t cr; 310 usb_cb_flags_t cf; 311 mblk_t *mp; 312 int err; 313 314 bzero(&req, sizeof (req)); 315 req.bmRequestType = USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_DEV_TO_HOST; 316 req.bRequest = RT2573_READ_MULTI_MAC; 317 req.wValue = 0; 318 req.wIndex = reg; 319 req.wLength = (uint16_t)len; 320 req.attrs = USB_ATTRS_AUTOCLEARING; 321 322 mp = NULL; 323 err = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp, 324 &cr, &cf, 0); 325 326 if (err != USB_SUCCESS) { 327 ral_debug(RAL_DBG_ERR, 328 "rum_read_multi(): could not read MAC register:" 329 "cr:%s(%d), cf:(%x)\n", 330 usb_str_cr(cr), cr, cf); 331 return; 332 } 333 334 bcopy(mp->b_rptr, buf, len); 335 freemsg(mp); 336 } 337 338 static uint32_t 339 rum_read(struct rum_softc *sc, uint16_t reg) 340 { 341 uint32_t val; 342 343 rum_read_multi(sc, reg, &val, sizeof (val)); 344 345 return (LE_32(val)); 346 } 347 348 static void 349 rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len) 350 { 351 usb_ctrl_setup_t req; 352 usb_cr_t cr; 353 usb_cb_flags_t cf; 354 mblk_t *mp; 355 int err; 356 357 bzero(&req, sizeof (req)); 358 req.bmRequestType = USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_HOST_TO_DEV; 359 req.bRequest = RT2573_WRITE_MULTI_MAC; 360 req.wValue = 0; 361 req.wIndex = reg; 362 req.wLength = (uint16_t)len; 363 req.attrs = USB_ATTRS_NONE; 364 365 if ((mp = allocb(len, BPRI_HI)) == NULL) { 366 ral_debug(RAL_DBG_ERR, "rum_write_multi(): failed alloc mblk."); 367 return; 368 } 369 370 bcopy(buf, mp->b_wptr, len); 371 mp->b_wptr += len; 372 373 err = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp, 374 &cr, &cf, 0); 375 376 if (err != USB_SUCCESS) { 377 ral_debug(RAL_DBG_USB, 378 "rum_write_multi(): could not write MAC register:" 379 "cr:%s(%d), cf:(%x)\n", 380 usb_str_cr(cr), cr, cf); 381 } 382 383 freemsg(mp); 384 } 385 386 static void 387 rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val) 388 { 389 uint32_t tmp = LE_32(val); 390 391 rum_write_multi(sc, reg, &tmp, sizeof (tmp)); 392 } 393 394 #define UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24)) 395 396 static int 397 rum_load_microcode(struct rum_softc *sc) 398 { 399 usb_ctrl_setup_t req; 400 usb_cr_t cr; 401 usb_cb_flags_t cf; 402 int err; 403 404 const uint8_t *ucode; 405 int size; 406 uint16_t reg = RT2573_MCU_CODE_BASE; 407 408 ucode = rt2573_ucode; 409 size = sizeof (rt2573_ucode); 410 411 /* copy firmware image into NIC */ 412 for (; size >= 4; reg += 4, ucode += 4, size -= 4) { 413 rum_write(sc, reg, UGETDW(ucode)); 414 /* rum_write(sc, reg, *(uint32_t *)(ucode)); */ 415 } 416 417 bzero(&req, sizeof (req)); 418 req.bmRequestType = USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_HOST_TO_DEV; 419 req.bRequest = RT2573_MCU_CNTL; 420 req.wValue = RT2573_MCU_RUN; 421 req.wIndex = 0; 422 req.wLength = 0; 423 req.attrs = USB_ATTRS_NONE; 424 425 err = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, NULL, 426 &cr, &cf, 0); 427 428 if (err != USB_SUCCESS) { 429 ral_debug(RAL_DBG_ERR, 430 "rum_load_microcode(): could not run firmware: " 431 "cr:%s(%d), cf:(%x)\n", 432 usb_str_cr(cr), cr, cf); 433 } 434 435 ral_debug(RAL_DBG_MSG, 436 "rum_load_microcode(%d): done\n", sizeof (rt2573_ucode)); 437 438 return (err); 439 } 440 441 static void 442 rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len) 443 { 444 usb_ctrl_setup_t req; 445 usb_cr_t cr; 446 usb_cb_flags_t cf; 447 mblk_t *mp; 448 int err; 449 450 bzero(&req, sizeof (req)); 451 req.bmRequestType = USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_DEV_TO_HOST; 452 req.bRequest = RT2573_READ_EEPROM; 453 req.wValue = 0; 454 req.wIndex = addr; 455 req.wLength = (uint16_t)len; 456 457 mp = NULL; 458 err = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp, 459 &cr, &cf, 0); 460 461 if (err != USB_SUCCESS) { 462 ral_debug(RAL_DBG_USB, 463 "rum_eeprom_read(): could not read EEPROM:" 464 "cr:%s(%d), cf:(%x)\n", 465 usb_str_cr(cr), cr, cf); 466 return; 467 } 468 469 bcopy(mp->b_rptr, buf, len); 470 freemsg(mp); 471 } 472 473 /* ARGSUSED */ 474 static void 475 rum_txeof(usb_pipe_handle_t pipe, usb_bulk_req_t *req) 476 { 477 struct rum_softc *sc = (struct rum_softc *)req->bulk_client_private; 478 struct ieee80211com *ic = &sc->sc_ic; 479 480 ral_debug(RAL_DBG_TX, 481 "rum_txeof(): cr:%s(%d), flags:0x%x, tx_queued:%d", 482 usb_str_cr(req->bulk_completion_reason), 483 req->bulk_completion_reason, 484 req->bulk_cb_flags, 485 sc->tx_queued); 486 487 if (req->bulk_completion_reason != USB_CR_OK) 488 sc->sc_tx_err++; 489 490 mutex_enter(&sc->tx_lock); 491 492 sc->tx_queued--; 493 sc->sc_tx_timer = 0; 494 495 if (sc->sc_need_sched) { 496 sc->sc_need_sched = 0; 497 mac_tx_update(ic->ic_mach); 498 } 499 500 mutex_exit(&sc->tx_lock); 501 usb_free_bulk_req(req); 502 } 503 504 /* ARGSUSED */ 505 static void 506 rum_rxeof(usb_pipe_handle_t pipe, usb_bulk_req_t *req) 507 { 508 struct rum_softc *sc = (struct rum_softc *)req->bulk_client_private; 509 struct ieee80211com *ic = &sc->sc_ic; 510 511 struct rum_rx_desc *desc; 512 struct ieee80211_frame *wh; 513 struct ieee80211_node *ni; 514 515 mblk_t *m, *mp; 516 int len, pktlen; 517 char *rxbuf; 518 519 mp = req->bulk_data; 520 req->bulk_data = NULL; 521 522 ral_debug(RAL_DBG_RX, 523 "rum_rxeof(): cr:%s(%d), flags:0x%x, rx_queued:%d", 524 usb_str_cr(req->bulk_completion_reason), 525 req->bulk_completion_reason, 526 req->bulk_cb_flags, 527 sc->rx_queued); 528 529 if (req->bulk_completion_reason != USB_CR_OK) { 530 sc->sc_rx_err++; 531 goto fail; 532 } 533 534 len = msgdsize(mp); 535 rxbuf = (char *)mp->b_rptr; 536 537 538 if (len < RT2573_RX_DESC_SIZE + sizeof (struct ieee80211_frame_min)) { 539 ral_debug(RAL_DBG_ERR, 540 "rum_rxeof(): xfer too short %d\n", len); 541 sc->sc_rx_err++; 542 goto fail; 543 } 544 545 /* rx descriptor is located at the head, different from RT2500USB */ 546 desc = (struct rum_rx_desc *)rxbuf; 547 548 if (LE_32(desc->flags) & RT2573_RX_CRC_ERROR) { 549 /* 550 * This should not happen since we did not request to receive 551 * those frames when we filled RT2573_TXRX_CSR0. 552 */ 553 ral_debug(RAL_DBG_ERR, "CRC error\n"); 554 sc->sc_rx_err++; 555 goto fail; 556 } 557 558 pktlen = (LE_32(desc->flags) >> 16) & 0xfff; 559 560 if (pktlen > (len - RT2573_RX_DESC_SIZE)) { 561 ral_debug(RAL_DBG_ERR, 562 "rum_rxeof(): pktlen mismatch <%d, %d>.\n", pktlen, len); 563 goto fail; 564 } 565 566 if ((m = allocb(pktlen, BPRI_MED)) == NULL) { 567 ral_debug(RAL_DBG_ERR, 568 "rum_rxeof(): allocate mblk failed.\n"); 569 sc->sc_rx_nobuf++; 570 goto fail; 571 } 572 573 bcopy(rxbuf + RT2573_RX_DESC_SIZE, m->b_rptr, pktlen); 574 m->b_wptr += pktlen; 575 576 wh = (struct ieee80211_frame *)m->b_rptr; 577 ni = ieee80211_find_rxnode(ic, wh); 578 579 /* send the frame to the 802.11 layer */ 580 (void) ieee80211_input(ic, m, ni, desc->rssi, 0); 581 582 /* node is no longer needed */ 583 ieee80211_free_node(ni); 584 585 fail: 586 mutex_enter(&sc->rx_lock); 587 sc->rx_queued--; 588 mutex_exit(&sc->rx_lock); 589 590 freemsg(mp); 591 usb_free_bulk_req(req); 592 593 if (RAL_IS_RUNNING(sc)) 594 (void) rum_rx_trigger(sc); 595 } 596 597 /* 598 * Return the expected ack rate for a frame transmitted at rate `rate'. 599 */ 600 static int 601 rum_ack_rate(struct ieee80211com *ic, int rate) 602 { 603 switch (rate) { 604 /* CCK rates */ 605 case 2: 606 return (2); 607 case 4: 608 case 11: 609 case 22: 610 return ((ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate); 611 612 /* OFDM rates */ 613 case 12: 614 case 18: 615 return (12); 616 case 24: 617 case 36: 618 return (24); 619 case 48: 620 case 72: 621 case 96: 622 case 108: 623 return (48); 624 } 625 626 /* default to 1Mbps */ 627 return (2); 628 } 629 630 /* 631 * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'. 632 * The function automatically determines the operating mode depending on the 633 * given rate. `flags' indicates whether short preamble is in use or not. 634 */ 635 static uint16_t 636 rum_txtime(int len, int rate, uint32_t flags) 637 { 638 uint16_t txtime; 639 640 if (RUM_RATE_IS_OFDM(rate)) { 641 /* IEEE Std 802.11a-1999, pp. 37 */ 642 txtime = (8 + 4 * len + 3 + rate - 1) / rate; 643 txtime = 16 + 4 + 4 * txtime + 6; 644 } else { 645 /* IEEE Std 802.11b-1999, pp. 28 */ 646 txtime = (16 * len + rate - 1) / rate; 647 if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) 648 txtime += 72 + 24; 649 else 650 txtime += 144 + 48; 651 } 652 return (txtime); 653 } 654 655 static uint8_t 656 rum_plcp_signal(int rate) 657 { 658 switch (rate) { 659 /* CCK rates (returned values are device-dependent) */ 660 case 2: return (0x0); 661 case 4: return (0x1); 662 case 11: return (0x2); 663 case 22: return (0x3); 664 665 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 666 case 12: return (0xb); 667 case 18: return (0xf); 668 case 24: return (0xa); 669 case 36: return (0xe); 670 case 48: return (0x9); 671 case 72: return (0xd); 672 case 96: return (0x8); 673 case 108: return (0xc); 674 675 /* unsupported rates (should not get there) */ 676 default: return (0xff); 677 } 678 } 679 680 static void 681 rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, 682 uint32_t flags, uint16_t xflags, int len, int rate) 683 { 684 struct ieee80211com *ic = &sc->sc_ic; 685 uint16_t plcp_length; 686 int remainder; 687 688 desc->flags = LE_32(flags); 689 desc->flags |= LE_32(RT2573_TX_VALID); 690 desc->flags |= LE_32(len << 16); 691 692 desc->xflags = LE_16(xflags); 693 694 desc->wme = LE_16(RT2573_QID(0) | RT2573_AIFSN(2) | 695 RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10)); 696 697 /* setup PLCP fields */ 698 desc->plcp_signal = rum_plcp_signal(rate); 699 desc->plcp_service = 4; 700 701 len += IEEE80211_CRC_LEN; 702 if (RUM_RATE_IS_OFDM(rate)) { 703 desc->flags |= LE_32(RT2573_TX_OFDM); 704 705 plcp_length = len & 0xfff; 706 desc->plcp_length_hi = plcp_length >> 6; 707 desc->plcp_length_lo = plcp_length & 0x3f; 708 } else { 709 plcp_length = (16 * len + rate - 1) / rate; 710 if (rate == 22) { 711 remainder = (16 * len) % 22; 712 if (remainder != 0 && remainder < 7) 713 desc->plcp_service |= RT2573_PLCP_LENGEXT; 714 } 715 desc->plcp_length_hi = plcp_length >> 8; 716 desc->plcp_length_lo = plcp_length & 0xff; 717 718 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) 719 desc->plcp_signal |= 0x08; 720 } 721 } 722 723 #define RUM_TX_TIMEOUT 5 724 725 static int 726 rum_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type) 727 { 728 struct rum_softc *sc = (struct rum_softc *)ic; 729 struct rum_tx_desc *desc; 730 731 struct ieee80211_frame *wh; 732 struct ieee80211_key *k; 733 734 uint16_t dur; 735 uint32_t flags = 0; 736 int rate, err = DDI_SUCCESS, rv; 737 738 struct ieee80211_node *ni = NULL; 739 mblk_t *m, *m0; 740 int off, mblen, pktlen, xferlen; 741 742 /* discard packets while suspending or not inited */ 743 if (!RAL_IS_RUNNING(sc)) { 744 freemsg(mp); 745 return (ENXIO); 746 } 747 748 mutex_enter(&sc->tx_lock); 749 750 if (sc->tx_queued > RAL_TX_LIST_COUNT) { 751 ral_debug(RAL_DBG_TX, "rum_send(): " 752 "no TX buffer available!\n"); 753 if ((type & IEEE80211_FC0_TYPE_MASK) == 754 IEEE80211_FC0_TYPE_DATA) { 755 sc->sc_need_sched = 1; 756 } 757 sc->sc_tx_nobuf++; 758 err = ENOMEM; 759 goto fail; 760 } 761 762 m = allocb(RAL_TXBUF_SIZE + RT2573_TX_DESC_SIZE, BPRI_MED); 763 if (m == NULL) { 764 ral_debug(RAL_DBG_ERR, "rum_send(): can't alloc mblk.\n"); 765 err = DDI_FAILURE; 766 goto fail; 767 } 768 769 m->b_rptr += RT2573_TX_DESC_SIZE; /* skip TX descriptor */ 770 m->b_wptr += RT2573_TX_DESC_SIZE; 771 772 for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) { 773 mblen = (uintptr_t)m0->b_wptr - (uintptr_t)m0->b_rptr; 774 (void) memcpy(m->b_rptr + off, m0->b_rptr, mblen); 775 off += mblen; 776 } 777 m->b_wptr += off; 778 779 wh = (struct ieee80211_frame *)m->b_rptr; 780 781 ni = ieee80211_find_txnode(ic, wh->i_addr1); 782 if (ni == NULL) { 783 err = DDI_FAILURE; 784 sc->sc_tx_err++; 785 freemsg(m); 786 goto fail; 787 } 788 789 if ((type & IEEE80211_FC0_TYPE_MASK) == 790 IEEE80211_FC0_TYPE_DATA) { 791 (void) ieee80211_encap(ic, m, ni); 792 } 793 794 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 795 k = ieee80211_crypto_encap(ic, m); 796 if (k == NULL) { 797 sc->sc_tx_err++; 798 err = DDI_FAILURE; 799 freemsg(m); 800 goto fail; 801 } 802 /* packet header may have moved, reset our local pointer */ 803 wh = (struct ieee80211_frame *)m->b_rptr; 804 } 805 806 m->b_rptr -= RT2573_TX_DESC_SIZE; /* restore */ 807 desc = (struct rum_tx_desc *)m->b_rptr; 808 809 if ((type & IEEE80211_FC0_TYPE_MASK) == 810 IEEE80211_FC0_TYPE_DATA) { /* DATA */ 811 if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) 812 rate = ic->ic_bss->in_rates.ir_rates[ic->ic_fixed_rate]; 813 else 814 rate = ni->in_rates.ir_rates[ni->in_txrate]; 815 816 rate &= IEEE80211_RATE_VAL; 817 if (rate <= 0) { 818 rate = 2; /* basic rate */ 819 } 820 821 822 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 823 flags |= RT2573_TX_NEED_ACK; 824 flags |= RT2573_TX_MORE_FRAG; 825 826 dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate), 827 ic->ic_flags) + sc->sifs; 828 *(uint16_t *)(uintptr_t)wh->i_dur = LE_16(dur); 829 } 830 } else { /* MGMT */ 831 rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; 832 833 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 834 flags |= RT2573_TX_NEED_ACK; 835 836 dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate), 837 ic->ic_flags) + sc->sifs; 838 *(uint16_t *)(uintptr_t)wh->i_dur = LE_16(dur); 839 840 /* tell hardware to add timestamp for probe responses */ 841 if ((wh->i_fc[0] & 842 (IEEE80211_FC0_TYPE_MASK | 843 IEEE80211_FC0_SUBTYPE_MASK)) == 844 (IEEE80211_FC0_TYPE_MGT | 845 IEEE80211_FC0_SUBTYPE_PROBE_RESP)) 846 flags |= RT2573_TX_TIMESTAMP; 847 } 848 } 849 850 pktlen = msgdsize(m) - RT2573_TX_DESC_SIZE; 851 rum_setup_tx_desc(sc, desc, flags, 0, pktlen, rate); 852 853 /* align end on a 4-bytes boundary */ 854 xferlen = (RT2573_TX_DESC_SIZE + pktlen + 3) & ~3; 855 856 /* 857 * No space left in the last URB to store the extra 4 bytes, force 858 * sending of another URB. 859 */ 860 if ((xferlen % 64) == 0) 861 xferlen += 4; 862 863 m->b_wptr = m->b_rptr + xferlen; 864 865 ral_debug(RAL_DBG_TX, "sending data frame len=%u rate=%u xfer len=%u\n", 866 pktlen, rate, xferlen); 867 868 rv = rum_tx_trigger(sc, m); 869 870 if (rv == 0) { 871 ic->ic_stats.is_tx_frags++; 872 ic->ic_stats.is_tx_bytes += pktlen; 873 } 874 875 fail: 876 if (ni != NULL) 877 ieee80211_free_node(ni); 878 879 if ((type & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA || 880 err == 0) { 881 freemsg(mp); 882 } 883 884 mutex_exit(&sc->tx_lock); 885 886 return (err); 887 } 888 889 static mblk_t * 890 rum_m_tx(void *arg, mblk_t *mp) 891 { 892 struct rum_softc *sc = (struct rum_softc *)arg; 893 struct ieee80211com *ic = &sc->sc_ic; 894 mblk_t *next; 895 896 /* 897 * No data frames go out unless we're associated; this 898 * should not happen as the 802.11 layer does not enable 899 * the xmit queue until we enter the RUN state. 900 */ 901 if (ic->ic_state != IEEE80211_S_RUN) { 902 ral_debug(RAL_DBG_ERR, "rum_m_tx(): " 903 "discard, state %u\n", ic->ic_state); 904 freemsgchain(mp); 905 return (NULL); 906 } 907 908 while (mp != NULL) { 909 next = mp->b_next; 910 mp->b_next = NULL; 911 if (rum_send(ic, mp, IEEE80211_FC0_TYPE_DATA) != DDI_SUCCESS) { 912 mp->b_next = next; 913 freemsgchain(mp); 914 return (NULL); 915 } 916 mp = next; 917 } 918 return (mp); 919 } 920 921 static void 922 rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val) 923 { 924 uint32_t tmp; 925 int ntries; 926 927 for (ntries = 0; ntries < 5; ntries++) { 928 if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY)) 929 break; 930 } 931 if (ntries == 5) { 932 ral_debug(RAL_DBG_ERR, 933 "rum_bbp_write(): could not write to BBP\n"); 934 return; 935 } 936 937 tmp = RT2573_BBP_BUSY | (reg & 0x7f) << 8 | val; 938 rum_write(sc, RT2573_PHY_CSR3, tmp); 939 } 940 941 static uint8_t 942 rum_bbp_read(struct rum_softc *sc, uint8_t reg) 943 { 944 uint32_t val; 945 int ntries; 946 947 for (ntries = 0; ntries < 5; ntries++) { 948 if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY)) 949 break; 950 } 951 if (ntries == 5) { 952 ral_debug(RAL_DBG_ERR, "rum_bbp_read(): could not read BBP\n"); 953 return (0); 954 } 955 956 val = RT2573_BBP_BUSY | RT2573_BBP_READ | reg << 8; 957 rum_write(sc, RT2573_PHY_CSR3, val); 958 959 for (ntries = 0; ntries < 100; ntries++) { 960 val = rum_read(sc, RT2573_PHY_CSR3); 961 if (!(val & RT2573_BBP_BUSY)) 962 return (val & 0xff); 963 drv_usecwait(1); 964 } 965 966 ral_debug(RAL_DBG_ERR, "rum_bbp_read(): could not read BBP\n"); 967 return (0); 968 } 969 970 static void 971 rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val) 972 { 973 uint32_t tmp; 974 int ntries; 975 976 for (ntries = 0; ntries < 5; ntries++) { 977 if (!(rum_read(sc, RT2573_PHY_CSR4) & RT2573_RF_BUSY)) 978 break; 979 } 980 if (ntries == 5) { 981 ral_debug(RAL_DBG_ERR, 982 "rum_rf_write(): could not write to RF\n"); 983 return; 984 } 985 986 tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | (val & 0xfffff) << 2 | 987 (reg & 3); 988 rum_write(sc, RT2573_PHY_CSR4, tmp); 989 990 /* remember last written value in sc */ 991 sc->rf_regs[reg] = val; 992 993 ral_debug(RAL_DBG_HW, "RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff); 994 } 995 996 static void 997 rum_select_antenna(struct rum_softc *sc) 998 { 999 uint8_t bbp4, bbp77; 1000 uint32_t tmp; 1001 1002 bbp4 = rum_bbp_read(sc, 4); 1003 bbp77 = rum_bbp_read(sc, 77); 1004 1005 /* make sure Rx is disabled before switching antenna */ 1006 tmp = rum_read(sc, RT2573_TXRX_CSR0); 1007 rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX); 1008 1009 rum_bbp_write(sc, 4, bbp4); 1010 rum_bbp_write(sc, 77, bbp77); 1011 1012 rum_write(sc, RT2573_TXRX_CSR0, tmp); 1013 } 1014 1015 /* 1016 * Enable multi-rate retries for frames sent at OFDM rates. 1017 * In 802.11b/g mode, allow fallback to CCK rates. 1018 */ 1019 static void 1020 rum_enable_mrr(struct rum_softc *sc) 1021 { 1022 struct ieee80211com *ic = &sc->sc_ic; 1023 uint32_t tmp; 1024 1025 tmp = rum_read(sc, RT2573_TXRX_CSR4); 1026 1027 tmp &= ~RT2573_MRR_CCK_FALLBACK; 1028 if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 1029 tmp |= RT2573_MRR_CCK_FALLBACK; 1030 tmp |= RT2573_MRR_ENABLED; 1031 1032 rum_write(sc, RT2573_TXRX_CSR4, tmp); 1033 } 1034 1035 static void 1036 rum_set_txpreamble(struct rum_softc *sc) 1037 { 1038 uint32_t tmp; 1039 1040 tmp = rum_read(sc, RT2573_TXRX_CSR4); 1041 1042 tmp &= ~RT2573_SHORT_PREAMBLE; 1043 if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE) 1044 tmp |= RT2573_SHORT_PREAMBLE; 1045 1046 rum_write(sc, RT2573_TXRX_CSR4, tmp); 1047 } 1048 1049 static void 1050 rum_set_basicrates(struct rum_softc *sc) 1051 { 1052 struct ieee80211com *ic = &sc->sc_ic; 1053 1054 /* update basic rate set */ 1055 if (ic->ic_curmode == IEEE80211_MODE_11B) { 1056 /* 11b basic rates: 1, 2Mbps */ 1057 rum_write(sc, RT2573_TXRX_CSR5, 0x3); 1058 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->in_chan)) { 1059 /* 11a basic rates: 6, 12, 24Mbps */ 1060 rum_write(sc, RT2573_TXRX_CSR5, 0x150); 1061 } else { 1062 /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */ 1063 rum_write(sc, RT2573_TXRX_CSR5, 0xf); 1064 } 1065 } 1066 1067 /* 1068 * Reprogram MAC/BBP to switch to a new band. Values taken from the reference 1069 * driver. 1070 */ 1071 static void 1072 rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c) 1073 { 1074 uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104; 1075 uint32_t tmp; 1076 1077 /* update all BBP registers that depend on the band */ 1078 bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c; 1079 bbp35 = 0x50; bbp97 = 0x48; bbp98 = 0x48; 1080 if (IEEE80211_IS_CHAN_5GHZ(c)) { 1081 bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c; 1082 bbp35 += 0x10; bbp97 += 0x10; bbp98 += 0x10; 1083 } 1084 if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) || 1085 (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) { 1086 bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10; 1087 } 1088 1089 sc->bbp17 = bbp17; 1090 rum_bbp_write(sc, 17, bbp17); 1091 rum_bbp_write(sc, 96, bbp96); 1092 rum_bbp_write(sc, 104, bbp104); 1093 1094 if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) || 1095 (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) { 1096 rum_bbp_write(sc, 75, 0x80); 1097 rum_bbp_write(sc, 86, 0x80); 1098 rum_bbp_write(sc, 88, 0x80); 1099 } 1100 1101 rum_bbp_write(sc, 35, bbp35); 1102 rum_bbp_write(sc, 97, bbp97); 1103 rum_bbp_write(sc, 98, bbp98); 1104 1105 tmp = rum_read(sc, RT2573_PHY_CSR0); 1106 tmp &= ~(RT2573_PA_PE_2GHZ | RT2573_PA_PE_5GHZ); 1107 if (IEEE80211_IS_CHAN_2GHZ(c)) 1108 tmp |= RT2573_PA_PE_2GHZ; 1109 else 1110 tmp |= RT2573_PA_PE_5GHZ; 1111 rum_write(sc, RT2573_PHY_CSR0, tmp); 1112 1113 /* 802.11a uses a 16 microseconds short interframe space */ 1114 sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10; 1115 } 1116 1117 static void 1118 rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c) 1119 { 1120 struct ieee80211com *ic = &sc->sc_ic; 1121 const struct rfprog *rfprog; 1122 uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT; 1123 int8_t power; 1124 uint_t i, chan; 1125 1126 chan = ieee80211_chan2ieee(ic, c); 1127 if (chan == 0 || chan == IEEE80211_CHAN_ANY) 1128 return; 1129 1130 /* select the appropriate RF settings based on what EEPROM says */ 1131 rfprog = (sc->rf_rev == RT2573_RF_5225 || 1132 sc->rf_rev == RT2573_RF_2527) ? rum_rf5225 : rum_rf5226; 1133 1134 /* find the settings for this channel (we know it exists) */ 1135 for (i = 0; rfprog[i].chan != chan; i++) { 1136 } 1137 1138 power = sc->txpow[i]; 1139 if (power < 0) { 1140 bbp94 += power; 1141 power = 0; 1142 } else if (power > 31) { 1143 bbp94 += power - 31; 1144 power = 31; 1145 } 1146 1147 /* 1148 * If we are switching from the 2GHz band to the 5GHz band or 1149 * vice-versa, BBP registers need to be reprogrammed. 1150 */ 1151 if (c->ich_flags != ic->ic_curchan->ich_flags) { 1152 rum_select_band(sc, c); 1153 rum_select_antenna(sc); 1154 } 1155 ic->ic_curchan = c; 1156 1157 rum_rf_write(sc, RT2573_RF1, rfprog[i].r1); 1158 rum_rf_write(sc, RT2573_RF2, rfprog[i].r2); 1159 rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7); 1160 rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10); 1161 1162 rum_rf_write(sc, RT2573_RF1, rfprog[i].r1); 1163 rum_rf_write(sc, RT2573_RF2, rfprog[i].r2); 1164 rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7 | 1); 1165 rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10); 1166 1167 rum_rf_write(sc, RT2573_RF1, rfprog[i].r1); 1168 rum_rf_write(sc, RT2573_RF2, rfprog[i].r2); 1169 rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7); 1170 rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10); 1171 1172 drv_usecwait(10); 1173 1174 /* enable smart mode for MIMO-capable RFs */ 1175 bbp3 = rum_bbp_read(sc, 3); 1176 1177 bbp3 &= ~RT2573_SMART_MODE; 1178 if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_2527) 1179 bbp3 |= RT2573_SMART_MODE; 1180 1181 rum_bbp_write(sc, 3, bbp3); 1182 1183 if (bbp94 != RT2573_BBPR94_DEFAULT) 1184 rum_bbp_write(sc, 94, bbp94); 1185 } 1186 1187 /* 1188 * Enable TSF synchronization and tell h/w to start sending beacons for IBSS 1189 * and HostAP operating modes. 1190 */ 1191 static void 1192 rum_enable_tsf_sync(struct rum_softc *sc) 1193 { 1194 struct ieee80211com *ic = &sc->sc_ic; 1195 uint32_t tmp; 1196 1197 if (ic->ic_opmode != IEEE80211_M_STA) { 1198 /* 1199 * Change default 16ms TBTT adjustment to 8ms. 1200 * Must be done before enabling beacon generation. 1201 */ 1202 rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8); 1203 } 1204 1205 tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000; 1206 1207 /* set beacon interval (in 1/16ms unit) */ 1208 tmp |= ic->ic_bss->in_intval * 16; 1209 1210 tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT; 1211 if (ic->ic_opmode == IEEE80211_M_STA) 1212 tmp |= RT2573_TSF_MODE(1); 1213 else 1214 tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON; 1215 1216 rum_write(sc, RT2573_TXRX_CSR9, tmp); 1217 } 1218 1219 /* ARGSUSED */ 1220 static void 1221 rum_update_slot(struct ieee80211com *ic, int onoff) 1222 { 1223 struct rum_softc *sc = (struct rum_softc *)ic; 1224 uint8_t slottime; 1225 uint32_t tmp; 1226 1227 slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; 1228 1229 tmp = rum_read(sc, RT2573_MAC_CSR9); 1230 tmp = (tmp & ~0xff) | slottime; 1231 rum_write(sc, RT2573_MAC_CSR9, tmp); 1232 1233 ral_debug(RAL_DBG_HW, "setting slot time to %uus\n", slottime); 1234 } 1235 1236 static void 1237 rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid) 1238 { 1239 uint32_t tmp; 1240 1241 tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24; 1242 rum_write(sc, RT2573_MAC_CSR4, tmp); 1243 1244 tmp = bssid[4] | bssid[5] << 8 | RT2573_ONE_BSSID << 16; 1245 rum_write(sc, RT2573_MAC_CSR5, tmp); 1246 } 1247 1248 static void 1249 rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr) 1250 { 1251 uint32_t tmp; 1252 1253 tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24; 1254 rum_write(sc, RT2573_MAC_CSR2, tmp); 1255 1256 tmp = addr[4] | addr[5] << 8 | 0xff << 16; 1257 rum_write(sc, RT2573_MAC_CSR3, tmp); 1258 1259 ral_debug(RAL_DBG_HW, 1260 "setting MAC address to " MACSTR "\n", MAC2STR(addr)); 1261 } 1262 1263 static void 1264 rum_update_promisc(struct rum_softc *sc) 1265 { 1266 uint32_t tmp; 1267 1268 tmp = rum_read(sc, RT2573_TXRX_CSR0); 1269 1270 tmp &= ~RT2573_DROP_NOT_TO_ME; 1271 if (!(sc->sc_rcr & RAL_RCR_PROMISC)) 1272 tmp |= RT2573_DROP_NOT_TO_ME; 1273 1274 rum_write(sc, RT2573_TXRX_CSR0, tmp); 1275 1276 ral_debug(RAL_DBG_HW, "%s promiscuous mode\n", 1277 (sc->sc_rcr & RAL_RCR_PROMISC) ? "entering" : "leaving"); 1278 } 1279 1280 static const char * 1281 rum_get_rf(int rev) 1282 { 1283 switch (rev) { 1284 case RT2573_RF_2527: return ("RT2527 (MIMO XR)"); 1285 case RT2573_RF_2528: return ("RT2528"); 1286 case RT2573_RF_5225: return ("RT5225 (MIMO XR)"); 1287 case RT2573_RF_5226: return ("RT5226"); 1288 default: return ("unknown"); 1289 } 1290 } 1291 1292 static void 1293 rum_read_eeprom(struct rum_softc *sc) 1294 { 1295 struct ieee80211com *ic = &sc->sc_ic; 1296 uint16_t val; 1297 1298 /* read MAC address */ 1299 rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, ic->ic_macaddr, 6); 1300 1301 rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2); 1302 val = LE_16(val); 1303 sc->rf_rev = (val >> 11) & 0x1f; 1304 sc->hw_radio = (val >> 10) & 0x1; 1305 sc->rx_ant = (val >> 4) & 0x3; 1306 sc->tx_ant = (val >> 2) & 0x3; 1307 sc->nb_ant = val & 0x3; 1308 1309 ral_debug(RAL_DBG_HW, "RF revision=%d\n", sc->rf_rev); 1310 1311 rum_eeprom_read(sc, RT2573_EEPROM_CONFIG2, &val, 2); 1312 val = LE_16(val); 1313 sc->ext_5ghz_lna = (val >> 6) & 0x1; 1314 sc->ext_2ghz_lna = (val >> 4) & 0x1; 1315 1316 ral_debug(RAL_DBG_HW, "External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n", 1317 sc->ext_2ghz_lna, sc->ext_5ghz_lna); 1318 1319 rum_eeprom_read(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET, &val, 2); 1320 val = LE_16(val); 1321 if ((val & 0xff) != 0xff) 1322 sc->rssi_2ghz_corr = (int8_t)(val & 0xff); /* signed */ 1323 1324 rum_eeprom_read(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET, &val, 2); 1325 val = LE_16(val); 1326 if ((val & 0xff) != 0xff) 1327 sc->rssi_5ghz_corr = (int8_t)(val & 0xff); /* signed */ 1328 1329 ral_debug(RAL_DBG_HW, "RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n", 1330 sc->rssi_2ghz_corr, sc->rssi_5ghz_corr); 1331 1332 rum_eeprom_read(sc, RT2573_EEPROM_FREQ_OFFSET, &val, 2); 1333 val = LE_16(val); 1334 if ((val & 0xff) != 0xff) 1335 sc->rffreq = val & 0xff; 1336 1337 ral_debug(RAL_DBG_HW, "RF freq=%d\n", sc->rffreq); 1338 1339 /* read Tx power for all a/b/g channels */ 1340 rum_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->txpow, 14); 1341 /* default Tx power for 802.11a channels */ 1342 (void) memset(sc->txpow + 14, 24, sizeof (sc->txpow) - 14); 1343 1344 /* read default values for BBP registers */ 1345 rum_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16); 1346 } 1347 1348 static int 1349 rum_bbp_init(struct rum_softc *sc) 1350 { 1351 int i, ntries; 1352 1353 /* wait for BBP to be ready */ 1354 for (ntries = 0; ntries < 100; ntries++) { 1355 const uint8_t val = rum_bbp_read(sc, 0); 1356 if (val != 0 && val != 0xff) 1357 break; 1358 drv_usecwait(1000); 1359 } 1360 if (ntries == 100) { 1361 ral_debug(RAL_DBG_ERR, "timeout waiting for BBP\n"); 1362 return (EIO); 1363 } 1364 1365 /* initialize BBP registers to default values */ 1366 for (i = 0; i < RUM_N(rum_def_bbp); i++) 1367 rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val); 1368 1369 /* write vendor-specific BBP values (from EEPROM) */ 1370 for (i = 0; i < 16; i++) { 1371 if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff) 1372 continue; 1373 rum_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val); 1374 } 1375 1376 return (0); 1377 } 1378 1379 /* 1380 * This function is called periodically (every 200ms) during scanning to 1381 * switch from one channel to another. 1382 */ 1383 static void 1384 rum_next_scan(void *arg) 1385 { 1386 struct rum_softc *sc = arg; 1387 struct ieee80211com *ic = &sc->sc_ic; 1388 1389 if (ic->ic_state == IEEE80211_S_SCAN) 1390 ieee80211_next_scan(ic); 1391 } 1392 1393 static int 1394 rum_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 1395 { 1396 struct rum_softc *sc = (struct rum_softc *)ic; 1397 enum ieee80211_state ostate; 1398 struct ieee80211_node *ni; 1399 int err; 1400 uint32_t tmp; 1401 1402 RAL_LOCK(sc); 1403 1404 ostate = ic->ic_state; 1405 1406 if (sc->sc_scan_id != 0) { 1407 (void) untimeout(sc->sc_scan_id); 1408 sc->sc_scan_id = 0; 1409 } 1410 1411 if (sc->sc_amrr_id != 0) { 1412 (void) untimeout(sc->sc_amrr_id); 1413 sc->sc_amrr_id = 0; 1414 } 1415 1416 switch (nstate) { 1417 case IEEE80211_S_INIT: 1418 if (ostate == IEEE80211_S_RUN) { 1419 /* abort TSF synchronization */ 1420 tmp = rum_read(sc, RT2573_TXRX_CSR9); 1421 rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); 1422 } 1423 break; 1424 1425 case IEEE80211_S_SCAN: 1426 rum_set_chan(sc, ic->ic_curchan); 1427 sc->sc_scan_id = timeout(rum_next_scan, (void *)sc, 1428 drv_usectohz(sc->dwelltime * 1000)); 1429 break; 1430 1431 case IEEE80211_S_AUTH: 1432 rum_set_chan(sc, ic->ic_curchan); 1433 break; 1434 1435 case IEEE80211_S_ASSOC: 1436 rum_set_chan(sc, ic->ic_curchan); 1437 break; 1438 1439 case IEEE80211_S_RUN: 1440 rum_set_chan(sc, ic->ic_curchan); 1441 1442 ni = ic->ic_bss; 1443 1444 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 1445 rum_update_slot(ic, 1); 1446 rum_enable_mrr(sc); 1447 rum_set_txpreamble(sc); 1448 rum_set_basicrates(sc); 1449 rum_set_bssid(sc, ni->in_bssid); 1450 } 1451 1452 if (ic->ic_opmode != IEEE80211_M_MONITOR) 1453 rum_enable_tsf_sync(sc); 1454 1455 /* enable automatic rate adaptation in STA mode */ 1456 if (ic->ic_opmode == IEEE80211_M_STA && 1457 ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) 1458 rum_amrr_start(sc, ni); 1459 break; 1460 } 1461 1462 RAL_UNLOCK(sc); 1463 1464 err = sc->sc_newstate(ic, nstate, arg); 1465 /* 1466 * Finally, start any timers. 1467 */ 1468 if (nstate == IEEE80211_S_RUN) 1469 ieee80211_start_watchdog(ic, 1); 1470 1471 return (err); 1472 } 1473 1474 static void 1475 rum_close_pipes(struct rum_softc *sc) 1476 { 1477 usb_flags_t flags = USB_FLAGS_SLEEP; 1478 1479 if (sc->sc_rx_pipeh != NULL) { 1480 usb_pipe_reset(sc->sc_dev, sc->sc_rx_pipeh, flags, NULL, 0); 1481 usb_pipe_close(sc->sc_dev, sc->sc_rx_pipeh, flags, NULL, 0); 1482 sc->sc_rx_pipeh = NULL; 1483 } 1484 1485 if (sc->sc_tx_pipeh != NULL) { 1486 usb_pipe_reset(sc->sc_dev, sc->sc_tx_pipeh, flags, NULL, 0); 1487 usb_pipe_close(sc->sc_dev, sc->sc_tx_pipeh, flags, NULL, 0); 1488 sc->sc_tx_pipeh = NULL; 1489 } 1490 } 1491 1492 static int 1493 rum_open_pipes(struct rum_softc *sc) 1494 { 1495 usb_ep_data_t *ep_node; 1496 usb_pipe_policy_t policy; 1497 int err; 1498 1499 ep_node = usb_lookup_ep_data(sc->sc_dev, sc->sc_udev, 0, 0, 0, 1500 USB_EP_ATTR_BULK, USB_EP_DIR_OUT); 1501 1502 bzero(&policy, sizeof (usb_pipe_policy_t)); 1503 policy.pp_max_async_reqs = RAL_TX_LIST_COUNT; 1504 1505 if ((err = usb_pipe_open(sc->sc_dev, 1506 &ep_node->ep_descr, &policy, USB_FLAGS_SLEEP, 1507 &sc->sc_tx_pipeh)) != USB_SUCCESS) { 1508 ral_debug(RAL_DBG_ERR, 1509 "rum_open_pipes(): %x failed to open tx pipe\n", err); 1510 goto fail; 1511 } 1512 1513 ep_node = usb_lookup_ep_data(sc->sc_dev, sc->sc_udev, 0, 0, 0, 1514 USB_EP_ATTR_BULK, USB_EP_DIR_IN); 1515 1516 bzero(&policy, sizeof (usb_pipe_policy_t)); 1517 policy.pp_max_async_reqs = RAL_RX_LIST_COUNT + 32; 1518 1519 if ((err = usb_pipe_open(sc->sc_dev, 1520 &ep_node->ep_descr, &policy, USB_FLAGS_SLEEP, 1521 &sc->sc_rx_pipeh)) != USB_SUCCESS) { 1522 ral_debug(RAL_DBG_ERR, 1523 "rum_open_pipes(): %x failed to open rx pipe\n", err); 1524 goto fail; 1525 } 1526 1527 return (USB_SUCCESS); 1528 1529 fail: 1530 if (sc->sc_rx_pipeh != NULL) { 1531 usb_pipe_close(sc->sc_dev, sc->sc_rx_pipeh, 1532 USB_FLAGS_SLEEP, NULL, 0); 1533 sc->sc_rx_pipeh = NULL; 1534 } 1535 1536 if (sc->sc_tx_pipeh != NULL) { 1537 usb_pipe_close(sc->sc_dev, sc->sc_tx_pipeh, 1538 USB_FLAGS_SLEEP, NULL, 0); 1539 sc->sc_tx_pipeh = NULL; 1540 } 1541 1542 return (USB_FAILURE); 1543 } 1544 1545 static int 1546 rum_tx_trigger(struct rum_softc *sc, mblk_t *mp) 1547 { 1548 usb_bulk_req_t *req; 1549 int err; 1550 1551 sc->sc_tx_timer = RUM_TX_TIMEOUT; 1552 1553 req = usb_alloc_bulk_req(sc->sc_dev, 0, USB_FLAGS_SLEEP); 1554 if (req == NULL) { 1555 ral_debug(RAL_DBG_ERR, 1556 "rum_tx_trigger(): failed to allocate req"); 1557 freemsg(mp); 1558 return (-1); 1559 } 1560 1561 req->bulk_len = msgdsize(mp); 1562 req->bulk_data = mp; 1563 req->bulk_client_private = (usb_opaque_t)sc; 1564 req->bulk_timeout = RUM_TX_TIMEOUT; 1565 req->bulk_attributes = USB_ATTRS_AUTOCLEARING; 1566 req->bulk_cb = rum_txeof; 1567 req->bulk_exc_cb = rum_txeof; 1568 req->bulk_completion_reason = 0; 1569 req->bulk_cb_flags = 0; 1570 1571 if ((err = usb_pipe_bulk_xfer(sc->sc_tx_pipeh, req, 0)) 1572 != USB_SUCCESS) { 1573 1574 ral_debug(RAL_DBG_ERR, "rum_tx_trigger(): " 1575 "failed to do tx xfer, %d", err); 1576 usb_free_bulk_req(req); 1577 return (-1); 1578 } 1579 1580 sc->tx_queued++; 1581 1582 return (0); 1583 } 1584 1585 static int 1586 rum_rx_trigger(struct rum_softc *sc) 1587 { 1588 usb_bulk_req_t *req; 1589 int err; 1590 1591 req = usb_alloc_bulk_req(sc->sc_dev, RAL_RXBUF_SIZE, USB_FLAGS_SLEEP); 1592 if (req == NULL) { 1593 ral_debug(RAL_DBG_ERR, 1594 "rum_rx_trigger(): failed to allocate req"); 1595 return (-1); 1596 } 1597 1598 req->bulk_len = RAL_RXBUF_SIZE; 1599 req->bulk_client_private = (usb_opaque_t)sc; 1600 req->bulk_timeout = 0; 1601 req->bulk_attributes = USB_ATTRS_SHORT_XFER_OK 1602 | USB_ATTRS_AUTOCLEARING; 1603 req->bulk_cb = rum_rxeof; 1604 req->bulk_exc_cb = rum_rxeof; 1605 req->bulk_completion_reason = 0; 1606 req->bulk_cb_flags = 0; 1607 1608 err = usb_pipe_bulk_xfer(sc->sc_rx_pipeh, req, 0); 1609 1610 if (err != USB_SUCCESS) { 1611 ral_debug(RAL_DBG_ERR, "rum_rx_trigger(): " 1612 "failed to do rx xfer, %d", err); 1613 usb_free_bulk_req(req); 1614 1615 return (-1); 1616 } 1617 1618 mutex_enter(&sc->rx_lock); 1619 sc->rx_queued++; 1620 mutex_exit(&sc->rx_lock); 1621 1622 return (0); 1623 } 1624 1625 static void 1626 rum_init_tx_queue(struct rum_softc *sc) 1627 { 1628 sc->tx_queued = 0; 1629 } 1630 1631 static int 1632 rum_init_rx_queue(struct rum_softc *sc) 1633 { 1634 int i; 1635 1636 sc->rx_queued = 0; 1637 1638 for (i = 0; i < RAL_RX_LIST_COUNT; i++) { 1639 if (rum_rx_trigger(sc) != 0) { 1640 return (USB_FAILURE); 1641 } 1642 } 1643 1644 return (USB_SUCCESS); 1645 } 1646 1647 static void 1648 rum_stop(struct rum_softc *sc) 1649 { 1650 struct ieee80211com *ic = &sc->sc_ic; 1651 uint32_t tmp; 1652 1653 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 1654 ieee80211_stop_watchdog(ic); /* stop the watchdog */ 1655 1656 RAL_LOCK(sc); 1657 1658 sc->sc_tx_timer = 0; 1659 sc->sc_flags &= ~RAL_FLAG_RUNNING; /* STOP */ 1660 1661 /* disable Rx */ 1662 tmp = rum_read(sc, RT2573_TXRX_CSR0); 1663 rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX); 1664 1665 /* reset ASIC */ 1666 rum_write(sc, RT2573_MAC_CSR1, 3); 1667 rum_write(sc, RT2573_MAC_CSR1, 0); 1668 1669 rum_close_pipes(sc); 1670 1671 RAL_UNLOCK(sc); 1672 } 1673 1674 static int 1675 rum_init(struct rum_softc *sc) 1676 { 1677 struct ieee80211com *ic = &sc->sc_ic; 1678 uint32_t tmp; 1679 int i, ntries; 1680 1681 rum_stop(sc); 1682 1683 /* initialize MAC registers to default values */ 1684 for (i = 0; i < RUM_N(rum_def_mac); i++) 1685 rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val); 1686 1687 /* set host ready */ 1688 rum_write(sc, RT2573_MAC_CSR1, 3); 1689 rum_write(sc, RT2573_MAC_CSR1, 0); 1690 1691 /* wait for BBP/RF to wakeup */ 1692 for (ntries = 0; ntries < 1000; ntries++) { 1693 if (rum_read(sc, RT2573_MAC_CSR12) & 8) 1694 break; 1695 rum_write(sc, RT2573_MAC_CSR12, 4); /* force wakeup */ 1696 drv_usecwait(1000); 1697 } 1698 if (ntries == 1000) { 1699 ral_debug(RAL_DBG_ERR, 1700 "rum_init(): timeout waiting for BBP/RF to wakeup\n"); 1701 goto fail; 1702 } 1703 1704 if (rum_bbp_init(sc) != 0) 1705 goto fail; 1706 1707 /* select default channel */ 1708 rum_select_band(sc, ic->ic_curchan); 1709 rum_select_antenna(sc); 1710 rum_set_chan(sc, ic->ic_curchan); 1711 1712 /* clear STA registers */ 1713 rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof (sc->sta)); 1714 1715 rum_set_macaddr(sc, ic->ic_macaddr); 1716 1717 /* initialize ASIC */ 1718 rum_write(sc, RT2573_MAC_CSR1, 4); 1719 1720 if (rum_open_pipes(sc) != USB_SUCCESS) { 1721 ral_debug(RAL_DBG_ERR, "rum_init(): " 1722 "could not open pipes.\n"); 1723 goto fail; 1724 } 1725 1726 rum_init_tx_queue(sc); 1727 1728 if (rum_init_rx_queue(sc) != USB_SUCCESS) 1729 goto fail; 1730 1731 /* update Rx filter */ 1732 tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff; 1733 tmp |= RT2573_DROP_PHY_ERROR | RT2573_DROP_CRC_ERROR; 1734 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 1735 tmp |= RT2573_DROP_CTL | RT2573_DROP_VER_ERROR | 1736 RT2573_DROP_ACKCTS; 1737 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 1738 tmp |= RT2573_DROP_TODS; 1739 if (!(sc->sc_rcr & RAL_RCR_PROMISC)) 1740 tmp |= RT2573_DROP_NOT_TO_ME; 1741 } 1742 1743 rum_write(sc, RT2573_TXRX_CSR0, tmp); 1744 sc->sc_flags |= RAL_FLAG_RUNNING; /* RUNNING */ 1745 1746 return (DDI_SUCCESS); 1747 fail: 1748 rum_stop(sc); 1749 return (DDI_FAILURE); 1750 } 1751 1752 static int 1753 rum_disconnect(dev_info_t *devinfo) 1754 { 1755 struct rum_softc *sc; 1756 struct ieee80211com *ic; 1757 1758 /* 1759 * We can't call rum_stop() here, since the hardware is removed, 1760 * we can't access the register anymore. 1761 */ 1762 sc = ddi_get_soft_state(rum_soft_state_p, ddi_get_instance(devinfo)); 1763 ASSERT(sc != NULL); 1764 1765 if (!RAL_IS_RUNNING(sc)) /* different device or not inited */ 1766 return (DDI_SUCCESS); 1767 1768 ic = &sc->sc_ic; 1769 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 1770 ieee80211_stop_watchdog(ic); /* stop the watchdog */ 1771 1772 RAL_LOCK(sc); 1773 1774 sc->sc_tx_timer = 0; 1775 sc->sc_flags &= ~RAL_FLAG_RUNNING; /* STOP */ 1776 1777 rum_close_pipes(sc); 1778 1779 RAL_UNLOCK(sc); 1780 1781 return (DDI_SUCCESS); 1782 } 1783 1784 static int 1785 rum_reconnect(dev_info_t *devinfo) 1786 { 1787 struct rum_softc *sc; 1788 int err; 1789 1790 sc = ddi_get_soft_state(rum_soft_state_p, ddi_get_instance(devinfo)); 1791 ASSERT(sc != NULL); 1792 1793 /* check device changes after disconnect */ 1794 if (usb_check_same_device(sc->sc_dev, NULL, USB_LOG_L2, -1, 1795 USB_CHK_BASIC | USB_CHK_CFG, NULL) != USB_SUCCESS) { 1796 ral_debug(RAL_DBG_ERR, "different device connected\n"); 1797 return (DDI_FAILURE); 1798 } 1799 1800 err = rum_load_microcode(sc); 1801 if (err != USB_SUCCESS) { 1802 ral_debug(RAL_DBG_ERR, "could not load 8051 microcode\n"); 1803 goto fail; 1804 } 1805 1806 err = rum_init(sc); 1807 fail: 1808 return (err); 1809 } 1810 1811 static void 1812 rum_resume(struct rum_softc *sc) 1813 { 1814 int err; 1815 1816 /* check device changes after suspend */ 1817 if (usb_check_same_device(sc->sc_dev, NULL, USB_LOG_L2, -1, 1818 USB_CHK_BASIC | USB_CHK_CFG, NULL) != USB_SUCCESS) { 1819 ral_debug(RAL_DBG_ERR, "no or different device connected\n"); 1820 return; 1821 } 1822 1823 err = rum_load_microcode(sc); 1824 if (err != USB_SUCCESS) { 1825 ral_debug(RAL_DBG_ERR, "could not load 8051 microcode\n"); 1826 return; 1827 } 1828 1829 (void) rum_init(sc); 1830 } 1831 1832 #define RUM_AMRR_MIN_SUCCESS_THRESHOLD 1 1833 #define RUM_AMRR_MAX_SUCCESS_THRESHOLD 10 1834 1835 /* 1836 * Naive implementation of the Adaptive Multi Rate Retry algorithm: 1837 * "IEEE 802.11 Rate Adaptation: A Practical Approach" 1838 * Mathieu Lacage, Hossein Manshaei, Thierry Turletti 1839 * INRIA Sophia - Projet Planete 1840 * http://www-sop.inria.fr/rapports/sophia/RR-5208.html 1841 * 1842 * This algorithm is particularly well suited for rum since it does not 1843 * require per-frame retry statistics. Note however that since h/w does 1844 * not provide per-frame stats, we can't do per-node rate adaptation and 1845 * thus automatic rate adaptation is only enabled in STA operating mode. 1846 */ 1847 #define is_success(amrr) \ 1848 ((amrr)->retrycnt < (amrr)->txcnt / 10) 1849 #define is_failure(amrr) \ 1850 ((amrr)->retrycnt > (amrr)->txcnt / 3) 1851 #define is_enough(amrr) \ 1852 ((amrr)->txcnt > 10) 1853 #define is_min_rate(ni) \ 1854 ((ni)->in_txrate == 0) 1855 #define is_max_rate(ni) \ 1856 ((ni)->in_txrate == (ni)->in_rates.ir_nrates - 1) 1857 #define increase_rate(ni) \ 1858 ((ni)->in_txrate++) 1859 #define decrease_rate(ni) \ 1860 ((ni)->in_txrate--) 1861 #define reset_cnt(amrr) do { \ 1862 (amrr)->txcnt = (amrr)->retrycnt = 0; \ 1863 _NOTE(CONSTCOND) \ 1864 } while (/* CONSTCOND */0) 1865 1866 static void 1867 rum_ratectl(struct rum_amrr *amrr, struct ieee80211_node *ni) 1868 { 1869 int need_change = 0; 1870 1871 if (is_success(amrr) && is_enough(amrr)) { 1872 amrr->success++; 1873 if (amrr->success >= amrr->success_threshold && 1874 !is_max_rate(ni)) { 1875 amrr->recovery = 1; 1876 amrr->success = 0; 1877 increase_rate(ni); 1878 need_change = 1; 1879 } else { 1880 amrr->recovery = 0; 1881 } 1882 } else if (is_failure(amrr)) { 1883 amrr->success = 0; 1884 if (!is_min_rate(ni)) { 1885 if (amrr->recovery) { 1886 amrr->success_threshold *= 2; 1887 if (amrr->success_threshold > 1888 RUM_AMRR_MAX_SUCCESS_THRESHOLD) 1889 amrr->success_threshold = 1890 RUM_AMRR_MAX_SUCCESS_THRESHOLD; 1891 } else { 1892 amrr->success_threshold = 1893 RUM_AMRR_MIN_SUCCESS_THRESHOLD; 1894 } 1895 decrease_rate(ni); 1896 need_change = 1; 1897 } 1898 amrr->recovery = 0; /* original paper was incorrect */ 1899 } 1900 1901 if (is_enough(amrr) || need_change) 1902 reset_cnt(amrr); 1903 } 1904 1905 static void 1906 rum_amrr_timeout(void *arg) 1907 { 1908 struct rum_softc *sc = (struct rum_softc *)arg; 1909 struct rum_amrr *amrr = &sc->amrr; 1910 1911 rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof (sc->sta)); 1912 1913 /* count TX retry-fail as Tx errors */ 1914 sc->sc_tx_err += LE_32(sc->sta[5]) >> 16; 1915 sc->sc_tx_retries += ((LE_32(sc->sta[4]) >> 16) + 1916 (LE_32(sc->sta[5]) & 0xffff)); 1917 1918 amrr->retrycnt = 1919 (LE_32(sc->sta[4]) >> 16) + /* TX one-retry ok count */ 1920 (LE_32(sc->sta[5]) & 0xffff) + /* TX more-retry ok count */ 1921 (LE_32(sc->sta[5]) >> 16); /* TX retry-fail count */ 1922 1923 amrr->txcnt = 1924 amrr->retrycnt + 1925 (LE_32(sc->sta[4]) & 0xffff); /* TX no-retry ok count */ 1926 1927 rum_ratectl(amrr, sc->sc_ic.ic_bss); 1928 1929 sc->sc_amrr_id = timeout(rum_amrr_timeout, (void *)sc, 1930 drv_usectohz(1000 * 1000)); /* 1 second */ 1931 } 1932 1933 static void 1934 rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni) 1935 { 1936 struct rum_amrr *amrr = &sc->amrr; 1937 int i; 1938 1939 /* clear statistic registers (STA_CSR0 to STA_CSR5) */ 1940 rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof (sc->sta)); 1941 1942 amrr->success = 0; 1943 amrr->recovery = 0; 1944 amrr->txcnt = amrr->retrycnt = 0; 1945 amrr->success_threshold = RUM_AMRR_MIN_SUCCESS_THRESHOLD; 1946 1947 /* set rate to some reasonable initial value */ 1948 for (i = ni->in_rates.ir_nrates - 1; 1949 i > 0 && (ni->in_rates.ir_rates[i] & IEEE80211_RATE_VAL) > 72; 1950 i--) { 1951 } 1952 1953 ni->in_txrate = i; 1954 1955 sc->sc_amrr_id = timeout(rum_amrr_timeout, (void *)sc, 1956 drv_usectohz(1000 * 1000)); /* 1 second */ 1957 } 1958 1959 void 1960 rum_watchdog(void *arg) 1961 { 1962 struct rum_softc *sc = arg; 1963 struct ieee80211com *ic = &sc->sc_ic; 1964 int ntimer = 0; 1965 1966 RAL_LOCK(sc); 1967 ic->ic_watchdog_timer = 0; 1968 1969 if (!RAL_IS_RUNNING(sc)) { 1970 RAL_UNLOCK(sc); 1971 return; 1972 } 1973 1974 if (sc->sc_tx_timer > 0) { 1975 if (--sc->sc_tx_timer == 0) { 1976 ral_debug(RAL_DBG_ERR, "tx timer timeout\n"); 1977 RAL_UNLOCK(sc); 1978 (void) rum_init(sc); 1979 (void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 1980 return; 1981 } 1982 } 1983 1984 if (ic->ic_state == IEEE80211_S_RUN) 1985 ntimer = 1; 1986 1987 RAL_UNLOCK(sc); 1988 1989 ieee80211_watchdog(ic); 1990 1991 if (ntimer) 1992 ieee80211_start_watchdog(ic, ntimer); 1993 } 1994 1995 static int 1996 rum_m_start(void *arg) 1997 { 1998 struct rum_softc *sc = (struct rum_softc *)arg; 1999 int err; 2000 2001 /* 2002 * initialize RT2501USB hardware 2003 */ 2004 err = rum_init(sc); 2005 if (err != DDI_SUCCESS) { 2006 ral_debug(RAL_DBG_ERR, "device configuration failed\n"); 2007 goto fail; 2008 } 2009 sc->sc_flags |= RAL_FLAG_RUNNING; /* RUNNING */ 2010 return (err); 2011 2012 fail: 2013 rum_stop(sc); 2014 return (err); 2015 } 2016 2017 static void 2018 rum_m_stop(void *arg) 2019 { 2020 struct rum_softc *sc = (struct rum_softc *)arg; 2021 2022 (void) rum_stop(sc); 2023 sc->sc_flags &= ~RAL_FLAG_RUNNING; /* STOP */ 2024 } 2025 2026 static int 2027 rum_m_unicst(void *arg, const uint8_t *macaddr) 2028 { 2029 struct rum_softc *sc = (struct rum_softc *)arg; 2030 struct ieee80211com *ic = &sc->sc_ic; 2031 2032 ral_debug(RAL_DBG_MSG, "rum_m_unicst(): " MACSTR "\n", 2033 MAC2STR(macaddr)); 2034 2035 IEEE80211_ADDR_COPY(ic->ic_macaddr, macaddr); 2036 (void) rum_set_macaddr(sc, (uint8_t *)macaddr); 2037 (void) rum_init(sc); 2038 2039 return (0); 2040 } 2041 2042 /*ARGSUSED*/ 2043 static int 2044 rum_m_multicst(void *arg, boolean_t add, const uint8_t *mca) 2045 { 2046 return (0); 2047 } 2048 2049 static int 2050 rum_m_promisc(void *arg, boolean_t on) 2051 { 2052 struct rum_softc *sc = (struct rum_softc *)arg; 2053 2054 if (on) { 2055 sc->sc_rcr |= RAL_RCR_PROMISC; 2056 sc->sc_rcr |= RAL_RCR_MULTI; 2057 } else { 2058 sc->sc_rcr &= ~RAL_RCR_PROMISC; 2059 sc->sc_rcr &= ~RAL_RCR_MULTI; 2060 } 2061 2062 rum_update_promisc(sc); 2063 return (0); 2064 } 2065 2066 /* 2067 * callback functions for /get/set properties 2068 */ 2069 static int 2070 rum_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 2071 uint_t wldp_length, const void *wldp_buf) 2072 { 2073 struct rum_softc *sc = (struct rum_softc *)arg; 2074 struct ieee80211com *ic = &sc->sc_ic; 2075 int err; 2076 2077 err = ieee80211_setprop(ic, pr_name, wldp_pr_num, 2078 wldp_length, wldp_buf); 2079 RAL_LOCK(sc); 2080 if (err == ENETRESET) { 2081 if (RAL_IS_RUNNING(sc)) { 2082 RAL_UNLOCK(sc); 2083 (void) rum_init(sc); 2084 (void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2085 RAL_LOCK(sc); 2086 } 2087 err = 0; 2088 } 2089 RAL_UNLOCK(sc); 2090 2091 return (err); 2092 } 2093 2094 static int 2095 rum_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 2096 uint_t wldp_length, void *wldp_buf) 2097 { 2098 struct rum_softc *sc = (struct rum_softc *)arg; 2099 int err; 2100 2101 err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num, 2102 wldp_length, wldp_buf); 2103 2104 return (err); 2105 } 2106 2107 static void 2108 rum_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 2109 mac_prop_info_handle_t prh) 2110 { 2111 struct rum_softc *sc = (struct rum_softc *)arg; 2112 2113 ieee80211_propinfo(&sc->sc_ic, pr_name, wldp_pr_num, prh); 2114 } 2115 2116 static void 2117 rum_m_ioctl(void* arg, queue_t *wq, mblk_t *mp) 2118 { 2119 struct rum_softc *sc = (struct rum_softc *)arg; 2120 struct ieee80211com *ic = &sc->sc_ic; 2121 int err; 2122 2123 err = ieee80211_ioctl(ic, wq, mp); 2124 RAL_LOCK(sc); 2125 if (err == ENETRESET) { 2126 if (RAL_IS_RUNNING(sc)) { 2127 RAL_UNLOCK(sc); 2128 (void) rum_init(sc); 2129 (void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2130 RAL_LOCK(sc); 2131 } 2132 } 2133 RAL_UNLOCK(sc); 2134 } 2135 2136 static int 2137 rum_m_stat(void *arg, uint_t stat, uint64_t *val) 2138 { 2139 struct rum_softc *sc = (struct rum_softc *)arg; 2140 ieee80211com_t *ic = &sc->sc_ic; 2141 ieee80211_node_t *ni; 2142 struct ieee80211_rateset *rs; 2143 2144 RAL_LOCK(sc); 2145 2146 ni = ic->ic_bss; 2147 rs = &ni->in_rates; 2148 2149 switch (stat) { 2150 case MAC_STAT_IFSPEED: 2151 *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ? 2152 (rs->ir_rates[ni->in_txrate] & IEEE80211_RATE_VAL) 2153 : ic->ic_fixed_rate) * 500000ull; 2154 break; 2155 case MAC_STAT_NOXMTBUF: 2156 *val = sc->sc_tx_nobuf; 2157 break; 2158 case MAC_STAT_NORCVBUF: 2159 *val = sc->sc_rx_nobuf; 2160 break; 2161 case MAC_STAT_IERRORS: 2162 *val = sc->sc_rx_err; 2163 break; 2164 case MAC_STAT_RBYTES: 2165 *val = ic->ic_stats.is_rx_bytes; 2166 break; 2167 case MAC_STAT_IPACKETS: 2168 *val = ic->ic_stats.is_rx_frags; 2169 break; 2170 case MAC_STAT_OBYTES: 2171 *val = ic->ic_stats.is_tx_bytes; 2172 break; 2173 case MAC_STAT_OPACKETS: 2174 *val = ic->ic_stats.is_tx_frags; 2175 break; 2176 case MAC_STAT_OERRORS: 2177 case WIFI_STAT_TX_FAILED: 2178 *val = sc->sc_tx_err; 2179 break; 2180 case WIFI_STAT_TX_RETRANS: 2181 *val = sc->sc_tx_retries; 2182 break; 2183 case WIFI_STAT_FCS_ERRORS: 2184 case WIFI_STAT_WEP_ERRORS: 2185 case WIFI_STAT_TX_FRAGS: 2186 case WIFI_STAT_MCAST_TX: 2187 case WIFI_STAT_RTS_SUCCESS: 2188 case WIFI_STAT_RTS_FAILURE: 2189 case WIFI_STAT_ACK_FAILURE: 2190 case WIFI_STAT_RX_FRAGS: 2191 case WIFI_STAT_MCAST_RX: 2192 case WIFI_STAT_RX_DUPS: 2193 RAL_UNLOCK(sc); 2194 return (ieee80211_stat(ic, stat, val)); 2195 default: 2196 RAL_UNLOCK(sc); 2197 return (ENOTSUP); 2198 } 2199 RAL_UNLOCK(sc); 2200 2201 return (0); 2202 } 2203 2204 static int 2205 rum_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) 2206 { 2207 struct rum_softc *sc; 2208 struct ieee80211com *ic; 2209 int err, i, ntries; 2210 uint32_t tmp; 2211 int instance; 2212 2213 char strbuf[32]; 2214 2215 wifi_data_t wd = { 0 }; 2216 mac_register_t *macp; 2217 2218 switch (cmd) { 2219 case DDI_ATTACH: 2220 break; 2221 case DDI_RESUME: 2222 sc = ddi_get_soft_state(rum_soft_state_p, 2223 ddi_get_instance(devinfo)); 2224 ASSERT(sc != NULL); 2225 rum_resume(sc); 2226 return (DDI_SUCCESS); 2227 default: 2228 return (DDI_FAILURE); 2229 } 2230 2231 instance = ddi_get_instance(devinfo); 2232 2233 if (ddi_soft_state_zalloc(rum_soft_state_p, instance) != DDI_SUCCESS) { 2234 ral_debug(RAL_DBG_MSG, "rum_attach(): " 2235 "unable to alloc soft_state_p\n"); 2236 return (DDI_FAILURE); 2237 } 2238 2239 sc = ddi_get_soft_state(rum_soft_state_p, instance); 2240 ic = (ieee80211com_t *)&sc->sc_ic; 2241 sc->sc_dev = devinfo; 2242 2243 if (usb_client_attach(devinfo, USBDRV_VERSION, 0) != USB_SUCCESS) { 2244 ral_debug(RAL_DBG_ERR, 2245 "rum_attach(): usb_client_attach failed\n"); 2246 goto fail1; 2247 } 2248 2249 if (usb_get_dev_data(devinfo, &sc->sc_udev, 2250 USB_PARSE_LVL_ALL, 0) != USB_SUCCESS) { 2251 sc->sc_udev = NULL; 2252 goto fail2; 2253 } 2254 2255 mutex_init(&sc->sc_genlock, NULL, MUTEX_DRIVER, NULL); 2256 mutex_init(&sc->tx_lock, NULL, MUTEX_DRIVER, NULL); 2257 mutex_init(&sc->rx_lock, NULL, MUTEX_DRIVER, NULL); 2258 2259 /* retrieve RT2573 rev. no */ 2260 for (ntries = 0; ntries < 1000; ntries++) { 2261 if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0) 2262 break; 2263 drv_usecwait(1000); 2264 } 2265 if (ntries == 1000) { 2266 ral_debug(RAL_DBG_ERR, 2267 "rum_attach(): timeout waiting for chip to settle\n"); 2268 goto fail3; 2269 } 2270 2271 /* retrieve MAC address and various other things from EEPROM */ 2272 rum_read_eeprom(sc); 2273 2274 ral_debug(RAL_DBG_MSG, "rum: MAC/BBP RT2573 (rev 0x%05x), RF %s\n", 2275 tmp, rum_get_rf(sc->rf_rev)); 2276 2277 err = rum_load_microcode(sc); 2278 if (err != USB_SUCCESS) { 2279 ral_debug(RAL_DBG_ERR, "could not load 8051 microcode\n"); 2280 goto fail3; 2281 } 2282 2283 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 2284 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ 2285 ic->ic_state = IEEE80211_S_INIT; 2286 2287 ic->ic_maxrssi = 63; 2288 ic->ic_set_shortslot = rum_update_slot; 2289 ic->ic_xmit = rum_send; 2290 2291 /* set device capabilities */ 2292 ic->ic_caps = 2293 IEEE80211_C_TXPMGT | /* tx power management */ 2294 IEEE80211_C_SHPREAMBLE | /* short preamble supported */ 2295 IEEE80211_C_SHSLOT; /* short slot time supported */ 2296 2297 ic->ic_caps |= IEEE80211_C_WPA; /* Support WPA/WPA2 */ 2298 2299 #define IEEE80211_CHAN_A \ 2300 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) 2301 2302 if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226) { 2303 /* set supported .11a rates */ 2304 ic->ic_sup_rates[IEEE80211_MODE_11A] = rum_rateset_11a; 2305 2306 /* set supported .11a channels */ 2307 for (i = 34; i <= 46; i += 4) { 2308 ic->ic_sup_channels[i].ich_freq = 2309 ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); 2310 ic->ic_sup_channels[i].ich_flags = IEEE80211_CHAN_A; 2311 } 2312 for (i = 36; i <= 64; i += 4) { 2313 ic->ic_sup_channels[i].ich_freq = 2314 ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); 2315 ic->ic_sup_channels[i].ich_flags = IEEE80211_CHAN_A; 2316 } 2317 for (i = 100; i <= 140; i += 4) { 2318 ic->ic_sup_channels[i].ich_freq = 2319 ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); 2320 ic->ic_sup_channels[i].ich_flags = IEEE80211_CHAN_A; 2321 } 2322 for (i = 149; i <= 165; i += 4) { 2323 ic->ic_sup_channels[i].ich_freq = 2324 ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); 2325 ic->ic_sup_channels[i].ich_flags = IEEE80211_CHAN_A; 2326 } 2327 } 2328 2329 /* set supported .11b and .11g rates */ 2330 ic->ic_sup_rates[IEEE80211_MODE_11B] = rum_rateset_11b; 2331 ic->ic_sup_rates[IEEE80211_MODE_11G] = rum_rateset_11g; 2332 2333 /* set supported .11b and .11g channels (1 through 14) */ 2334 for (i = 1; i <= 14; i++) { 2335 ic->ic_sup_channels[i].ich_freq = 2336 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); 2337 ic->ic_sup_channels[i].ich_flags = 2338 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | 2339 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; 2340 } 2341 2342 ieee80211_attach(ic); 2343 2344 /* register WPA door */ 2345 ieee80211_register_door(ic, ddi_driver_name(devinfo), 2346 ddi_get_instance(devinfo)); 2347 2348 /* override state transition machine */ 2349 sc->sc_newstate = ic->ic_newstate; 2350 ic->ic_newstate = rum_newstate; 2351 ic->ic_watchdog = rum_watchdog; 2352 ieee80211_media_init(ic); 2353 ic->ic_def_txkey = 0; 2354 2355 sc->sc_rcr = 0; 2356 sc->dwelltime = 300; 2357 sc->sc_flags = 0; 2358 2359 /* 2360 * Provide initial settings for the WiFi plugin; whenever this 2361 * information changes, we need to call mac_plugindata_update() 2362 */ 2363 wd.wd_opmode = ic->ic_opmode; 2364 wd.wd_secalloc = WIFI_SEC_NONE; 2365 IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid); 2366 2367 if ((macp = mac_alloc(MAC_VERSION)) == NULL) { 2368 ral_debug(RAL_DBG_ERR, "rum_attach(): " 2369 "MAC version mismatch\n"); 2370 goto fail3; 2371 } 2372 2373 macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI; 2374 macp->m_driver = sc; 2375 macp->m_dip = devinfo; 2376 macp->m_src_addr = ic->ic_macaddr; 2377 macp->m_callbacks = &rum_m_callbacks; 2378 macp->m_min_sdu = 0; 2379 macp->m_max_sdu = IEEE80211_MTU; 2380 macp->m_pdata = &wd; 2381 macp->m_pdata_size = sizeof (wd); 2382 2383 err = mac_register(macp, &ic->ic_mach); 2384 mac_free(macp); 2385 if (err != 0) { 2386 ral_debug(RAL_DBG_ERR, "rum_attach(): " 2387 "mac_register() err %x\n", err); 2388 goto fail3; 2389 } 2390 2391 if (usb_register_hotplug_cbs(devinfo, rum_disconnect, 2392 rum_reconnect) != USB_SUCCESS) { 2393 ral_debug(RAL_DBG_ERR, 2394 "rum_attach() failed to register events"); 2395 goto fail4; 2396 } 2397 2398 /* 2399 * Create minor node of type DDI_NT_NET_WIFI 2400 */ 2401 (void) snprintf(strbuf, sizeof (strbuf), "%s%d", 2402 "rum", instance); 2403 err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR, 2404 instance + 1, DDI_NT_NET_WIFI, 0); 2405 2406 if (err != DDI_SUCCESS) 2407 ral_debug(RAL_DBG_ERR, "ddi_create_minor_node() failed\n"); 2408 2409 /* 2410 * Notify link is down now 2411 */ 2412 mac_link_update(ic->ic_mach, LINK_STATE_DOWN); 2413 return (DDI_SUCCESS); 2414 2415 fail4: 2416 (void) mac_unregister(ic->ic_mach); 2417 fail3: 2418 mutex_destroy(&sc->sc_genlock); 2419 mutex_destroy(&sc->tx_lock); 2420 mutex_destroy(&sc->rx_lock); 2421 fail2: 2422 usb_client_detach(sc->sc_dev, sc->sc_udev); 2423 fail1: 2424 ddi_soft_state_free(rum_soft_state_p, ddi_get_instance(devinfo)); 2425 2426 return (DDI_FAILURE); 2427 } 2428 2429 static int 2430 rum_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd) 2431 { 2432 struct rum_softc *sc; 2433 2434 sc = ddi_get_soft_state(rum_soft_state_p, ddi_get_instance(devinfo)); 2435 ASSERT(sc != NULL); 2436 2437 switch (cmd) { 2438 case DDI_DETACH: 2439 break; 2440 case DDI_SUSPEND: 2441 if (RAL_IS_RUNNING(sc)) 2442 (void) rum_stop(sc); 2443 return (DDI_SUCCESS); 2444 default: 2445 return (DDI_FAILURE); 2446 } 2447 2448 rum_stop(sc); 2449 usb_unregister_hotplug_cbs(devinfo); 2450 2451 /* 2452 * Unregister from the MAC layer subsystem 2453 */ 2454 if (mac_unregister(sc->sc_ic.ic_mach) != 0) 2455 return (DDI_FAILURE); 2456 2457 /* 2458 * detach ieee80211 layer 2459 */ 2460 ieee80211_detach(&sc->sc_ic); 2461 2462 mutex_destroy(&sc->sc_genlock); 2463 mutex_destroy(&sc->tx_lock); 2464 mutex_destroy(&sc->rx_lock); 2465 2466 /* pipes will be closed in rum_stop() */ 2467 usb_client_detach(devinfo, sc->sc_udev); 2468 sc->sc_udev = NULL; 2469 2470 ddi_remove_minor_node(devinfo, NULL); 2471 ddi_soft_state_free(rum_soft_state_p, ddi_get_instance(devinfo)); 2472 2473 return (DDI_SUCCESS); 2474 } 2475 2476 int 2477 _info(struct modinfo *modinfop) 2478 { 2479 return (mod_info(&modlinkage, modinfop)); 2480 } 2481 2482 int 2483 _init(void) 2484 { 2485 int status; 2486 2487 status = ddi_soft_state_init(&rum_soft_state_p, 2488 sizeof (struct rum_softc), 1); 2489 if (status != 0) 2490 return (status); 2491 2492 mac_init_ops(&rum_dev_ops, "rum"); 2493 status = mod_install(&modlinkage); 2494 if (status != 0) { 2495 mac_fini_ops(&rum_dev_ops); 2496 ddi_soft_state_fini(&rum_soft_state_p); 2497 } 2498 return (status); 2499 } 2500 2501 int 2502 _fini(void) 2503 { 2504 int status; 2505 2506 status = mod_remove(&modlinkage); 2507 if (status == 0) { 2508 mac_fini_ops(&rum_dev_ops); 2509 ddi_soft_state_fini(&rum_soft_state_p); 2510 } 2511 return (status); 2512 }