1 /*
2 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /*
7 * Copyright (c) 2006
8 * Damien Bergamini <damien.bergamini@free.fr>
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 RT2561, RT2561S and RT2661 chipset driver
25 * http://www.ralinktech.com/
26 */
27
28 #include <sys/types.h>
29 #include <sys/byteorder.h>
30 #include <sys/conf.h>
31 #include <sys/cmn_err.h>
32 #include <sys/stat.h>
33 #include <sys/ddi.h>
34 #include <sys/sunddi.h>
35 #include <sys/strsubr.h>
36 #include <sys/ethernet.h>
37 #include <inet/common.h>
38 #include <inet/nd.h>
39 #include <inet/mi.h>
40 #include <sys/note.h>
41 #include <sys/stream.h>
42 #include <sys/strsun.h>
43 #include <sys/modctl.h>
44 #include <sys/devops.h>
45 #include <sys/dlpi.h>
46 #include <sys/mac_provider.h>
47 #include <sys/mac_wifi.h>
48 #include <sys/net80211.h>
49 #include <sys/net80211_proto.h>
50 #include <sys/varargs.h>
51 #include <sys/policy.h>
52 #include <sys/pci.h>
53 #include <sys/crypto/common.h>
54 #include <sys/crypto/api.h>
55 #include <inet/wifi_ioctl.h>
56
57 #include "rt2661_reg.h"
58 #include "rt2661_var.h"
59 #include "rt2661_ucode.h"
60
61 #define RT2661_DBG_80211 (1 << 0)
62 #define RT2661_DBG_DMA (1 << 1)
63 #define RT2661_DBG_EEPROM (1 << 2)
64 #define RT2661_DBG_FW (1 << 3)
65 #define RT2661_DBG_HW (1 << 4)
66 #define RT2661_DBG_INTR (1 << 5)
67 #define RT2661_DBG_RX (1 << 6)
68 #define RT2661_DBG_SCAN (1 << 7)
69 #define RT2661_DBG_TX (1 << 8)
70 #define RT2661_DBG_RADIO (1 << 9)
71 #define RT2661_DBG_RESUME (1 << 10)
72 #define RT2661_DBG_MSG (1 << 11)
73
74 uint32_t rt2661_dbg_flags = 0;
75
76 #ifdef DEBUG
77 #define RWD_DEBUG \
78 rt2661_debug
79 #else
80 #define RWD_DEBUG
81 #endif
82
83 static void *rt2661_soft_state_p = NULL;
84
85 static const uint8_t *ucode = NULL;
86 int usize;
87
88 static const struct {
89 uint32_t reg;
90 uint32_t val;
91 } rt2661_def_mac[] = {
92 RT2661_DEF_MAC
93 };
94
95 static const struct {
96 uint8_t reg;
97 uint8_t val;
98 } rt2661_def_bbp[] = {
99 RT2661_DEF_BBP
100 };
101
102 static const struct rfprog {
103 uint8_t chan;
104 uint32_t r1, r2, r3, r4;
105 } rt2661_rf5225_1[] = {
106 RT2661_RF5225_1
107 }, rt2661_rf5225_2[] = {
108 RT2661_RF5225_2
109 };
110
111 /*
112 * PIO access attributes for registers
113 */
114 static ddi_device_acc_attr_t rt2661_csr_accattr = {
115 DDI_DEVICE_ATTR_V0,
116 DDI_STRUCTURE_LE_ACC,
117 DDI_STRICTORDER_ACC
118 };
119
120 /*
121 * DMA access attributes for descriptors: NOT to be byte swapped.
122 */
123 static ddi_device_acc_attr_t rt2661_desc_accattr = {
124 DDI_DEVICE_ATTR_V0,
125 DDI_STRUCTURE_LE_ACC,
126 DDI_STRICTORDER_ACC
127 };
128
129 static ddi_device_acc_attr_t rt2661_buf_accattr = {
130 DDI_DEVICE_ATTR_V0,
131 DDI_NEVERSWAP_ACC,
132 DDI_STRICTORDER_ACC,
133 DDI_DEFAULT_ACC
134 };
135
136 /*
137 * Describes the chip's DMA engine
138 */
139 static ddi_dma_attr_t rt2661_dma_attr = {
140 DMA_ATTR_V0, /* dma_attr version */
141 0x0, /* dma_attr_addr_lo */
142 0xffffffffU, /* dma_attr_addr_hi */
143 0xffffffffU, /* dma_attr_count_max */
144 1, /* dma_attr_align */
145 0x00000fff, /* dma_attr_burstsizes */
146 1, /* dma_attr_minxfer */
147 0xffffffffU, /* dma_attr_maxxfer */
148 0xffffffffU, /* dma_attr_seg */
149 1, /* dma_attr_sgllen */
150 1, /* dma_attr_granular */
151 0 /* dma_attr_flags */
152 };
153
154 static const struct ieee80211_rateset rt2661_rateset_11b =
155 { 4, { 2, 4, 11, 22 } };
156
157 static const struct ieee80211_rateset rt2661_rateset_11g =
158 { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
159
160
161 static const char *rt2661_get_rf(int);
162
163 static void rt2661_read_eeprom(struct rt2661_softc *);
164 static uint16_t rt2661_eeprom_read(struct rt2661_softc *, uint8_t);
165 static int rt2661_load_microcode(struct rt2661_softc *,
166 const uint8_t *, int);
167
168 static int rt2661_alloc_dma_mem(dev_info_t *, ddi_dma_attr_t *, size_t,
169 ddi_device_acc_attr_t *, uint_t, uint_t, struct dma_area *);
170 static void rt2661_free_dma_mem(struct dma_area *);
171 static int rt2661_alloc_tx_ring(struct rt2661_softc *,
172 struct rt2661_tx_ring *, int);
173 static void rt2661_reset_tx_ring(struct rt2661_softc *,
174 struct rt2661_tx_ring *);
175 static void rt2661_free_tx_ring(struct rt2661_softc *,
176 struct rt2661_tx_ring *);
177 static int rt2661_alloc_rx_ring(struct rt2661_softc *,
178 struct rt2661_rx_ring *, int);
179 static void rt2661_reset_rx_ring(struct rt2661_softc *,
180 struct rt2661_rx_ring *);
181 static void rt2661_free_rx_ring(struct rt2661_softc *,
182 struct rt2661_rx_ring *);
183 static void rt2661_tx_dma_intr(struct rt2661_softc *,
184 struct rt2661_tx_ring *);
185 static void rt2661_tx_intr(struct rt2661_softc *);
186 static void rt2661_rx_intr(struct rt2661_softc *);
187 static uint_t rt2661_softintr(caddr_t, caddr_t);
188 static void rt2661_mcu_wakeup(struct rt2661_softc *);
189 static void rt2661_mcu_cmd_intr(struct rt2661_softc *);
190 static uint_t rt2661_intr(caddr_t, caddr_t);
191
192 static uint16_t rt2661_txtime(int, int, uint32_t);
193 static int rt2661_ack_rate(struct ieee80211com *, int);
194 static uint8_t rt2661_plcp_signal(int);
195 static void rt2661_setup_tx_desc(struct rt2661_softc *,
196 struct rt2661_tx_desc *, uint32_t, uint16_t, int,
197 int, int);
198
199 static int rt2661_get_rssi(struct rt2661_softc *, uint8_t);
200
201 static int rt2661_send(ieee80211com_t *, mblk_t *);
202 static int rt2661_mgmt_send(ieee80211com_t *, mblk_t *, uint8_t);
203
204 static void rt2661_amrr_node_init(const struct rt2661_amrr *,
205 struct rt2661_amrr_node *);
206 static void rt2661_amrr_choose(struct rt2661_amrr *,
207 struct ieee80211_node *, struct rt2661_amrr_node *);
208
209 static void rt2661_update_promisc(struct rt2661_softc *);
210 static void rt2661_updateslot(struct ieee80211com *, int);
211 static void rt2661_set_slottime(struct rt2661_softc *);
212 static void rt2661_enable_mrr(struct rt2661_softc *);
213 static void rt2661_set_txpreamble(struct rt2661_softc *);
214 static void rt2661_set_basicrates(struct rt2661_softc *);
215 static void rt2661_set_bssid(struct rt2661_softc *, const uint8_t *);
216 static void rt2661_newassoc(struct ieee80211com *, struct ieee80211_node *);
217 static void rt2661_updatestats(void *);
218 static void rt2661_rx_tune(struct rt2661_softc *);
219 static void rt2661_enable_tsf_sync(struct rt2661_softc *);
220 static int rt2661_newstate(struct ieee80211com *,
221 enum ieee80211_state, int);
222
223 static void rt2661_set_macaddr(struct rt2661_softc *, const uint8_t *);
224 static int rt2661_bbp_init(struct rt2661_softc *);
225 static uint8_t rt2661_bbp_read(struct rt2661_softc *, uint8_t);
226 static void rt2661_bbp_write(struct rt2661_softc *, uint8_t, uint8_t);
227 static void rt2661_select_band(struct rt2661_softc *,
228 struct ieee80211_channel *);
229 static void rt2661_select_antenna(struct rt2661_softc *);
230 static void rt2661_rf_write(struct rt2661_softc *, uint8_t, uint32_t);
231 static void rt2661_set_chan(struct rt2661_softc *,
232 struct ieee80211_channel *);
233
234 static void rt2661_stop_locked(struct rt2661_softc *);
235 static int rt2661_init(struct rt2661_softc *);
236 static void rt2661_stop(struct rt2661_softc *);
237 /*
238 * device operations
239 */
240 static int rt2661_attach(dev_info_t *, ddi_attach_cmd_t);
241 static int rt2661_detach(dev_info_t *, ddi_detach_cmd_t);
242 static int rt2661_quiesce(dev_info_t *);
243
244 /*
245 * Module Loading Data & Entry Points
246 */
247 DDI_DEFINE_STREAM_OPS(rwd_dev_ops, nulldev, nulldev, rt2661_attach,
248 rt2661_detach, nodev, NULL, D_MP, NULL, rt2661_quiesce);
249
250 static struct modldrv rwd_modldrv = {
251 &mod_driverops, /* Type of module. This one is a driver */
252 "Ralink RT2661 driver v1.1", /* short description */
253 &rwd_dev_ops /* driver specific ops */
254 };
255
256 static struct modlinkage modlinkage = {
257 MODREV_1,
258 { (void *)&rwd_modldrv, NULL }
259 };
260
261 static int rt2661_m_stat(void *, uint_t, uint64_t *);
262 static int rt2661_m_start(void *);
263 static void rt2661_m_stop(void *);
264 static int rt2661_m_promisc(void *, boolean_t);
265 static int rt2661_m_multicst(void *, boolean_t, const uint8_t *);
266 static int rt2661_m_unicst(void *, const uint8_t *);
267 static mblk_t *rt2661_m_tx(void *, mblk_t *);
268 static void rt2661_m_ioctl(void *, queue_t *, mblk_t *);
269 static int rt2661_m_setprop(void *arg, const char *pr_name,
270 mac_prop_id_t wldp_pr_num,
271 uint_t wldp_length, const void *wldp_buf);
272 static int rt2661_m_getprop(void *arg, const char *pr_name,
273 mac_prop_id_t wldp_pr_num, uint_t wldp_length,
274 void *wldp_buf);
275 static void rt2661_m_propinfo(void *arg, const char *pr_name,
276 mac_prop_id_t wldp_pr_num, mac_prop_info_handle_t mph);
277
278 static mac_callbacks_t rt2661_m_callbacks = {
279 MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO,
280 rt2661_m_stat,
281 rt2661_m_start,
282 rt2661_m_stop,
283 rt2661_m_promisc,
284 rt2661_m_multicst,
285 rt2661_m_unicst,
286 rt2661_m_tx,
287 NULL,
288 rt2661_m_ioctl,
289 NULL,
290 NULL,
291 NULL,
292 rt2661_m_setprop,
293 rt2661_m_getprop,
294 rt2661_m_propinfo
295 };
296
297 #ifdef DEBUG
298 void
299 rt2661_debug(uint32_t dbg_flags, const int8_t *fmt, ...)
300 {
301 va_list args;
302
303 if (dbg_flags & rt2661_dbg_flags) {
304 va_start(args, fmt);
305 vcmn_err(CE_CONT, fmt, args);
306 va_end(args);
307 }
308 }
309 #endif
310
311 /*
312 * Read 16 bits at address 'addr' from the serial EEPROM (either 93C46 or
313 * 93C66).
314 */
315 static uint16_t
316 rt2661_eeprom_read(struct rt2661_softc *sc, uint8_t addr)
317 {
318 uint32_t tmp;
319 uint16_t val;
320 int n;
321
322 /* clock C once before the first command */
323 RT2661_EEPROM_CTL(sc, 0);
324
325 RT2661_EEPROM_CTL(sc, RT2661_S);
326 RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
327 RT2661_EEPROM_CTL(sc, RT2661_S);
328
329 /* write start bit (1) */
330 RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D);
331 RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D | RT2661_C);
332
333 /* write READ opcode (10) */
334 RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D);
335 RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D | RT2661_C);
336 RT2661_EEPROM_CTL(sc, RT2661_S);
337 RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
338
339 /* write address (A5-A0 or A7-A0) */
340 n = (RT2661_READ(sc, RT2661_E2PROM_CSR) & RT2661_93C46) ? 5 : 7;
341 for (; n >= 0; n--) {
342 RT2661_EEPROM_CTL(sc, RT2661_S |
343 (((addr >> n) & 1) << RT2661_SHIFT_D));
344 RT2661_EEPROM_CTL(sc, RT2661_S |
345 (((addr >> n) & 1) << RT2661_SHIFT_D) | RT2661_C);
346 }
347
348 RT2661_EEPROM_CTL(sc, RT2661_S);
349
350 /* read data Q15-Q0 */
351 val = 0;
352 for (n = 15; n >= 0; n--) {
353 RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
354 tmp = RT2661_READ(sc, RT2661_E2PROM_CSR);
355 val |= ((tmp & RT2661_Q) >> RT2661_SHIFT_Q) << n;
356 RT2661_EEPROM_CTL(sc, RT2661_S);
357 }
358
359 RT2661_EEPROM_CTL(sc, 0);
360
361 /* clear Chip Select and clock C */
362 RT2661_EEPROM_CTL(sc, RT2661_S);
363 RT2661_EEPROM_CTL(sc, 0);
364 RT2661_EEPROM_CTL(sc, RT2661_C);
365
366 return (val);
367 }
368
369
370 static void
371 rt2661_read_eeprom(struct rt2661_softc *sc)
372 {
373 struct ieee80211com *ic = &sc->sc_ic;
374 uint16_t val;
375 int i;
376
377 /* read MAC address */
378 val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC01);
379 ic->ic_macaddr[0] = val & 0xff;
380 ic->ic_macaddr[1] = val >> 8;
381
382 val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC23);
383 ic->ic_macaddr[2] = val & 0xff;
384 ic->ic_macaddr[3] = val >> 8;
385
386 val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC45);
387 ic->ic_macaddr[4] = val & 0xff;
388 ic->ic_macaddr[5] = val >> 8;
389
390 val = rt2661_eeprom_read(sc, RT2661_EEPROM_ANTENNA);
391 /* XXX: test if different from 0xffff? */
392 sc->rf_rev = (val >> 11) & 0x1f;
393 sc->hw_radio = (val >> 10) & 0x1;
394 sc->rx_ant = (val >> 4) & 0x3;
395 sc->tx_ant = (val >> 2) & 0x3;
396 sc->nb_ant = val & 0x3;
397
398 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
399 "RF revision=%d\n", sc->rf_rev);
400
401 val = rt2661_eeprom_read(sc, RT2661_EEPROM_CONFIG2);
402 sc->ext_5ghz_lna = (val >> 6) & 0x1;
403 sc->ext_2ghz_lna = (val >> 4) & 0x1;
404
405 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
406 "External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
407 sc->ext_2ghz_lna, sc->ext_5ghz_lna);
408
409 val = rt2661_eeprom_read(sc, RT2661_EEPROM_RSSI_2GHZ_OFFSET);
410 if ((val & 0xff) != 0xff)
411 sc->rssi_2ghz_corr = (int8_t)(val & 0xff);
412
413 val = rt2661_eeprom_read(sc, RT2661_EEPROM_RSSI_5GHZ_OFFSET);
414 if ((val & 0xff) != 0xff)
415 sc->rssi_5ghz_corr = (int8_t)(val & 0xff);
416
417 /* adjust RSSI correction for external low-noise amplifier */
418 if (sc->ext_2ghz_lna)
419 sc->rssi_2ghz_corr -= 14;
420 if (sc->ext_5ghz_lna)
421 sc->rssi_5ghz_corr -= 14;
422
423 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
424 "RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
425 sc->rssi_2ghz_corr, sc->rssi_5ghz_corr);
426
427 val = rt2661_eeprom_read(sc, RT2661_EEPROM_FREQ_OFFSET);
428 if ((val >> 8) != 0xff)
429 sc->rfprog = (val >> 8) & 0x3;
430 if ((val & 0xff) != 0xff)
431 sc->rffreq = val & 0xff;
432
433 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
434 "RF prog=%d\nRF freq=%d\n", sc->rfprog, sc->rffreq);
435
436 /* read Tx power for all a/b/g channels */
437 for (i = 0; i < 19; i++) {
438 val = rt2661_eeprom_read(sc, RT2661_EEPROM_TXPOWER + i);
439 sc->txpow[i * 2] = (int8_t)(val >> 8);
440 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
441 "Channel=%d Tx power=%d\n",
442 rt2661_rf5225_1[i * 2].chan, sc->txpow[i * 2]);
443 sc->txpow[i * 2 + 1] = (int8_t)(val & 0xff);
444 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
445 "Channel=%d Tx power=%d\n",
446 rt2661_rf5225_1[i * 2 + 1].chan, sc->txpow[i * 2 + 1]);
447 }
448
449 /* read vendor-specific BBP values */
450 for (i = 0; i < 16; i++) {
451 val = rt2661_eeprom_read(sc, RT2661_EEPROM_BBP_BASE + i);
452 if (val == 0 || val == 0xffff)
453 continue;
454 sc->bbp_prom[i].reg = val >> 8;
455 sc->bbp_prom[i].val = val & 0xff;
456 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
457 "BBP R%d=%02x\n", sc->bbp_prom[i].reg,
458 sc->bbp_prom[i].val);
459 }
460 }
461
462 static const char *
463 rt2661_get_rf(int rev)
464 {
465 switch (rev) {
466 case RT2661_RF_5225: return "RT5225";
467 case RT2661_RF_5325: return "RT5325 (MIMO XR)";
468 case RT2661_RF_2527: return "RT2527";
469 case RT2661_RF_2529: return "RT2529 (MIMO XR)";
470 default: return "unknown";
471 }
472 }
473
474 static int
475 rt2661_load_microcode(struct rt2661_softc *sc, const uint8_t *ucode_p, int size)
476 {
477 int ntries;
478 uint32_t off, i;
479 const uint8_t *fptr;
480
481 fptr = ucode_p;
482 off = RT2661_MCU_CODE_BASE;
483
484 /* reset 8051 */
485 RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET);
486
487 /* cancel any pending Host to MCU command */
488 RT2661_WRITE(sc, RT2661_H2M_MAILBOX_CSR, 0);
489 RT2661_WRITE(sc, RT2661_M2H_CMD_DONE_CSR, 0xffffffff);
490 RT2661_WRITE(sc, RT2661_HOST_CMD_CSR, 0);
491
492 /* write 8051's microcode */
493 RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR,
494 RT2661_MCU_RESET | RT2661_MCU_SEL);
495 /* RT2661_WRITE_REGION_1(sc, RT2661_MCU_CODE_BASE, ucode, size); */
496
497 for (i = 0; i < size; i++) {
498 RT2661_MEM_WRITE1(sc, off++, *fptr++);
499 }
500
501 RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET);
502
503 /* kick 8051's ass */
504 RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR, 0);
505
506 /* wait for 8051 to initialize */
507 for (ntries = 0; ntries < 500; ntries++) {
508 if (RT2661_READ(sc, RT2661_MCU_CNTL_CSR) & RT2661_MCU_READY)
509 break;
510 DELAY(100);
511 }
512 if (ntries == 500) {
513 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_load_microcode(): "
514 "timeout waiting for MCU to initialize\n");
515 return (RT2661_FAILURE);
516 }
517
518 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_load_microcode(): "
519 "MCU initialized successfully\n");
520 return (RT2661_SUCCESS);
521 }
522
523 /*
524 * Allocate an DMA memory and a DMA handle for accessing it
525 */
526 static int
527 rt2661_alloc_dma_mem(dev_info_t *devinfo, ddi_dma_attr_t *dma_attr,
528 size_t memsize, ddi_device_acc_attr_t *attr_p, uint_t alloc_flags,
529 uint_t bind_flags, struct dma_area *dma_p)
530 {
531 int err;
532
533 /*
534 * Allocate handle
535 */
536 err = ddi_dma_alloc_handle(devinfo, dma_attr,
537 DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl);
538 if (err != DDI_SUCCESS) {
539 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_allo_dma_mem(): "
540 "failed to alloc handle\n");
541 goto fail1;
542 }
543
544 /*
545 * Allocate memory
546 */
547 err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p,
548 alloc_flags, DDI_DMA_SLEEP, NULL, &dma_p->mem_va,
549 &dma_p->alength, &dma_p->acc_hdl);
550 if (err != DDI_SUCCESS) {
551 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_alloc_dma_mem(): "
552 "failed to alloc mem\n");
553 goto fail2;
554 }
555
556 /*
557 * Bind the two together
558 */
559 err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL,
560 dma_p->mem_va, dma_p->alength, bind_flags,
561 DDI_DMA_SLEEP, NULL, &dma_p->cookie, &dma_p->ncookies);
562 if (err != DDI_DMA_MAPPED) {
563 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_alloc_dma_mem(): "
564 "failed to bind handle\n");
565 goto fail3;
566 }
567
568 if (dma_p->ncookies != 1) {
569 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_alloc_dma_mem(): "
570 "failed to alloc cookies\n");
571 goto fail4;
572 }
573
574 dma_p->nslots = ~0U;
575 dma_p->size = ~0U;
576 dma_p->token = ~0U;
577 dma_p->offset = 0;
578 return (DDI_SUCCESS);
579
580 fail4:
581 (void) ddi_dma_unbind_handle(dma_p->dma_hdl);
582 fail3:
583 ddi_dma_mem_free(&dma_p->acc_hdl);
584 fail2:
585 ddi_dma_free_handle(&dma_p->dma_hdl);
586 fail1:
587 return (err);
588 }
589
590 static void
591 rt2661_free_dma_mem(struct dma_area *dma_p)
592 {
593 if (dma_p->dma_hdl != NULL) {
594 (void) ddi_dma_unbind_handle(dma_p->dma_hdl);
595 if (dma_p->acc_hdl != NULL) {
596 ddi_dma_mem_free(&dma_p->acc_hdl);
597 dma_p->acc_hdl = NULL;
598 }
599 ddi_dma_free_handle(&dma_p->dma_hdl);
600 dma_p->ncookies = 0;
601 dma_p->dma_hdl = NULL;
602 }
603 }
604
605 /*ARGSUSED*/
606 static int
607 rt2661_alloc_tx_ring(struct rt2661_softc *sc,
608 struct rt2661_tx_ring *ring, int count)
609 {
610 struct rt2661_tx_desc *desc;
611 struct rt2661_tx_data *data;
612 int i, err, size, len;
613
614 size = count * RT2661_TX_DESC_SIZE;
615 len = count * sizeof (struct rt2661_tx_data);
616
617 ring->count = count;
618 ring->queued = 0;
619 ring->cur = 0;
620 ring->next = 0;
621 ring->stat = 0;
622
623 err = rt2661_alloc_dma_mem(sc->sc_dev, &rt2661_dma_attr, size,
624 &rt2661_desc_accattr, DDI_DMA_CONSISTENT,
625 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
626 &ring->txdesc_dma);
627 if (err != DDI_SUCCESS) {
628 RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_alloc_tx_ring(): "
629 "failed to alloc dma mem\n");
630 goto fail1;
631 }
632
633 ring->desc = (struct rt2661_tx_desc *)ring->txdesc_dma.mem_va;
634 (void) bzero(ring->desc, size);
635 ring->paddr = ring->txdesc_dma.cookie.dmac_address;
636
637 ring->data = kmem_zalloc(len, KM_NOSLEEP);
638 if (ring->data == NULL) {
639 RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_alloc_tx_ring(): "
640 "failed to alloc tx buffer\n");
641 goto fail2;
642 }
643
644 for (i = 0; i < count; i++) {
645 desc = &ring->desc[i];
646 data = &ring->data[i];
647 err = rt2661_alloc_dma_mem(sc->sc_dev,
648 &rt2661_dma_attr, sc->sc_dmabuf_size,
649 &rt2661_buf_accattr, DDI_DMA_CONSISTENT,
650 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
651 &data->txdata_dma);
652 if (err != DDI_SUCCESS) {
653 RWD_DEBUG(RT2661_DBG_DMA,
654 "rwd: rt2661_alloc_tx_ring(): "
655 "failed to alloc tx buffer dma\n");
656 while (i >= 0) {
657 rt2661_free_dma_mem(&ring->data[i].txdata_dma);
658 i--;
659 }
660 goto fail3;
661 }
662 desc->addr[0] = data->txdata_dma.cookie.dmac_address;
663 data->buf = data->txdata_dma.mem_va;
664 data->paddr = data->txdata_dma.cookie.dmac_address;
665 }
666
667 (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
668 0, size, DDI_DMA_SYNC_FORDEV);
669 return (DDI_SUCCESS);
670 fail3:
671 if (ring->data)
672 kmem_free(ring->data,
673 count * sizeof (struct rt2661_tx_data));
674 fail2:
675 rt2661_free_dma_mem(&ring->txdesc_dma);
676 fail1:
677 return (err);
678 }
679
680 static void
681 rt2661_reset_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring)
682 {
683 struct rt2661_tx_desc *desc;
684 struct rt2661_tx_data *data;
685 int i;
686
687 for (i = 0; i < ring->count; i++) {
688 desc = &ring->desc[i];
689 data = &ring->data[i];
690
691 if (data->ni != NULL) {
692 ieee80211_free_node(data->ni);
693 data->ni = NULL;
694 }
695
696 desc->flags = 0;
697 }
698
699 if (!RT2661_IS_FASTREBOOT(sc))
700 (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl, 0,
701 ring->count * sizeof (struct rt2661_tx_desc),
702 DDI_DMA_SYNC_FORDEV);
703
704 ring->queued = 0;
705 ring->cur = ring->next = ring->stat = 0;
706 }
707
708
709 /*ARGSUSED*/
710 static void
711 rt2661_free_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring)
712 {
713 struct rt2661_tx_data *data;
714 int i;
715
716 if (ring->desc != NULL) {
717 rt2661_free_dma_mem(&ring->txdesc_dma);
718 }
719
720 if (ring->data != NULL) {
721 for (i = 0; i < ring->count; i++) {
722 data = &ring->data[i];
723 rt2661_free_dma_mem(&data->txdata_dma);
724 if (data->ni != NULL) {
725 ieee80211_free_node(data->ni);
726 data->ni = NULL;
727 }
728 }
729 kmem_free(ring->data,
730 ring->count * sizeof (struct rt2661_tx_data));
731 }
732 }
733
734 /*ARGSUSED*/
735 static int
736 rt2661_alloc_rx_ring(struct rt2661_softc *sc,
737 struct rt2661_rx_ring *ring, int count)
738 {
739 struct rt2661_rx_desc *desc;
740 struct rt2661_rx_data *data;
741 int i, err, len, size;
742
743 size = count * RT2661_RX_DESC_SIZE;
744 len = count * sizeof (struct rt2661_rx_data);
745
746 ring->count = count;
747 ring->cur = 0;
748 ring->next = 0;
749
750 err = rt2661_alloc_dma_mem(sc->sc_dev, &rt2661_dma_attr, size,
751 &rt2661_desc_accattr, DDI_DMA_CONSISTENT,
752 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
753 &ring->rxdesc_dma);
754 if (err != DDI_SUCCESS) {
755 RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_alloc_rx_ring(): "
756 "failed to alloc dma mem\n");
757 goto fail1;
758 }
759
760 ring->desc = (struct rt2661_rx_desc *)ring->rxdesc_dma.mem_va;
761 (void) bzero(ring->desc, size);
762 ring->paddr = ring->rxdesc_dma.cookie.dmac_address;
763
764 ring->data = kmem_zalloc(len, KM_NOSLEEP);
765 if (ring->data == NULL) {
766 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_alloc_rx_ring(): "
767 "failed to alloc rx buffer\n");
768 goto fail2;
769 }
770
771 for (i = 0; i < count; i++) {
772 desc = &ring->desc[i];
773 data = &ring->data[i];
774 err = rt2661_alloc_dma_mem(sc->sc_dev,
775 &rt2661_dma_attr, sc->sc_dmabuf_size,
776 &rt2661_buf_accattr, DDI_DMA_CONSISTENT,
777 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
778 &data->rxdata_dma);
779 if (err != DDI_SUCCESS) {
780 RWD_DEBUG(RT2661_DBG_DMA,
781 "rwd: rt2661_alloc_rx_ring(): "
782 "failed to alloc rx buffer dma\n");
783 while (i >= 0) {
784 rt2661_free_dma_mem(&ring->data[i].rxdata_dma);
785 i--;
786 }
787 goto fail3;
788 }
789 data->buf = data->rxdata_dma.mem_va;
790 data->paddr = data->rxdata_dma.cookie.dmac_address;
791 desc->flags = LE_32(RT2661_RX_BUSY);
792 desc->physaddr = LE_32(data->paddr);
793 }
794
795 (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl,
796 0, size, DDI_DMA_SYNC_FORDEV);
797 return (DDI_SUCCESS);
798 fail3:
799 if (ring->data)
800 kmem_free(ring->data,
801 count * sizeof (struct rt2661_rx_data));
802 fail2:
803 rt2661_free_dma_mem(&ring->rxdesc_dma);
804 fail1:
805 return (err);
806 }
807
808 static void
809 rt2661_reset_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring)
810 {
811 int i;
812
813 for (i = 0; i < ring->count; i++)
814 ring->desc[i].flags = LE_32(RT2661_RX_BUSY);
815
816 if (!RT2661_IS_FASTREBOOT(sc))
817 (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl, 0,
818 ring->count * sizeof (struct rt2661_rx_ring),
819 DDI_DMA_SYNC_FORKERNEL);
820
821 ring->cur = ring->next = 0;
822 }
823
824 /*ARGSUSED*/
825 static void
826 rt2661_free_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring)
827 {
828 struct rt2661_rx_data *data;
829 int i;
830
831 if (ring->desc != NULL) {
832 rt2661_free_dma_mem(&ring->rxdesc_dma);
833 }
834
835 if (ring->data != NULL) {
836 for (i = 0; i < ring->count; i++) {
837 data = &ring->data[i];
838 rt2661_free_dma_mem(&data->rxdata_dma);
839 }
840 kmem_free(ring->data,
841 ring->count * sizeof (struct rt2661_rx_data));
842 }
843 }
844
845 static void
846 rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *ring)
847 {
848 struct rt2661_tx_desc *desc;
849 struct rt2661_tx_data *data;
850
851 for (;;) {
852 desc = &ring->desc[ring->next];
853 data = &ring->data[ring->next];
854
855 (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
856 ring->next * RT2661_TX_DESC_SIZE,
857 RT2661_TX_DESC_SIZE,
858 DDI_DMA_SYNC_FORKERNEL);
859
860 if ((LE_32(desc->flags) & RT2661_TX_BUSY) ||
861 !(LE_32(desc->flags) & RT2661_TX_VALID))
862 break;
863
864 (void) ddi_dma_sync(data->txdata_dma.dma_hdl,
865 0, sc->sc_dmabuf_size,
866 DDI_DMA_SYNC_FORDEV);
867
868 /* descriptor is no longer valid */
869 desc->flags &= ~LE_32(RT2661_TX_VALID);
870
871 (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
872 ring->next * RT2661_TX_DESC_SIZE,
873 RT2661_TX_DESC_SIZE,
874 DDI_DMA_SYNC_FORDEV);
875
876 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_dma_intr(): "
877 "tx dma done q=%p idx=%u\n", ring, ring->next);
878
879 if (++ring->next >= ring->count) /* faster than % count */
880 ring->next = 0;
881 }
882 }
883
884 static void
885 rt2661_tx_intr(struct rt2661_softc *sc)
886 {
887 struct ieee80211com *ic = &sc->sc_ic;
888 struct rt2661_tx_ring *ring;
889 struct rt2661_tx_data *data;
890 struct rt2661_node *rn;
891
892 uint32_t val;
893 int qid, retrycnt;
894
895 for (;;) {
896 val = RT2661_READ(sc, RT2661_STA_CSR4);
897 if (!(val & RT2661_TX_STAT_VALID))
898 break;
899
900 /* retrieve the queue in which this frame was send */
901 qid = RT2661_TX_QID(val);
902 ring = (qid <= 3) ? &sc->txq[qid] : &sc->mgtq;
903
904 /* retrieve rate control algorithm context */
905 data = &ring->data[ring->stat];
906 rn = (struct rt2661_node *)data->ni;
907
908 /* if no frame has been sent, ignore */
909 if (rn == NULL) {
910 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): "
911 "no frame has been send, ignore\n");
912 continue;
913 }
914
915 switch (RT2661_TX_RESULT(val)) {
916 case RT2661_TX_SUCCESS:
917 retrycnt = RT2661_TX_RETRYCNT(val);
918
919 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): "
920 "data frame sent successfully after "
921 "%d retries\n", retrycnt);
922 rn->amn.amn_txcnt++;
923 if (retrycnt > 0) {
924 rn->amn.amn_retrycnt++;
925 sc->sc_tx_retries++;
926 }
927 break;
928 case RT2661_TX_RETRY_FAIL:
929 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): "
930 "sending data frame failed (too much retries)\n");
931 rn->amn.amn_txcnt++;
932 rn->amn.amn_retrycnt++;
933 break;
934 default:
935 /* other failure */
936 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr():"
937 "sending data frame failed 0x%08x\n", val);
938 }
939
940 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): "
941 "tx done q=%d idx=%u\n", qid, ring->stat);
942
943 ieee80211_free_node(data->ni);
944 data->ni = NULL;
945
946 ring->queued--;
947
948 /* faster than % count */
949 if (++ring->stat >= ring->count)
950 ring->stat = 0;
951
952 if (sc->sc_need_sched) {
953 sc->sc_need_sched = 0;
954 mac_tx_update(ic->ic_mach);
955 }
956 }
957 sc->sc_tx_timer = 0;
958 }
959
960 static void
961 rt2661_rx_intr(struct rt2661_softc *sc)
962 {
963 struct ieee80211com *ic = &sc->sc_ic;
964 struct rt2661_rx_ring *ring;
965 struct rt2661_rx_desc *desc;
966 struct rt2661_rx_data *data;
967 struct ieee80211_frame *wh;
968 struct ieee80211_node *ni;
969
970 mblk_t *m;
971 uint8_t *rxbuf;
972 uint32_t pktlen;
973
974 mutex_enter(&sc->sc_rxlock);
975 ring = &sc->rxq;
976
977 for (;;) {
978 int rssi;
979
980 desc = &ring->desc[ring->cur];
981 data = &ring->data[ring->cur];
982
983 (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl,
984 ring->cur * RT2661_RX_DESC_SIZE,
985 RT2661_RX_DESC_SIZE,
986 DDI_DMA_SYNC_FORKERNEL);
987
988
989 if (LE_32(desc->flags) & RT2661_RX_BUSY)
990 break;
991
992 if ((LE_32(desc->flags) & RT2661_RX_PHY_ERROR) ||
993 (LE_32(desc->flags) & RT2661_RX_CRC_ERROR)) {
994 /*
995 * This should not happen since we did not request
996 * to receive those frames when we filled TXRX_CSR0.
997 */
998 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_intr(): "
999 "PHY or CRC error flags 0x%08x\n",
1000 LE_32(desc->flags));
1001 sc->sc_rx_err++;
1002 goto skip;
1003 }
1004
1005 if ((LE_32(desc->flags) & RT2661_RX_CIPHER_MASK) != 0) {
1006 sc->sc_rx_err++;
1007 goto skip;
1008 }
1009
1010 (void) ddi_dma_sync(data->rxdata_dma.dma_hdl,
1011 0, sc->sc_dmabuf_size,
1012 DDI_DMA_SYNC_FORCPU);
1013
1014 rxbuf = (uint8_t *)data->rxdata_dma.mem_va;
1015 desc->physaddr = LE_32(data->rxdata_dma.cookie.dmac_address);
1016 pktlen = (LE_32(desc->flags) >> 16) & 0xfff;
1017 if ((pktlen < sizeof (struct ieee80211_frame_min)) ||
1018 (pktlen > sc->sc_dmabuf_size)) {
1019 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_intr(): "
1020 "bad fram length=%u\n", pktlen);
1021 sc->sc_rx_err++;
1022 goto skip;
1023 }
1024
1025 if ((m = allocb(pktlen, BPRI_MED)) == NULL) {
1026 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_intr(): "
1027 "allocate mblk failed.\n");
1028 sc->sc_rx_nobuf++;
1029 goto skip;
1030 }
1031
1032 bcopy(rxbuf, m->b_rptr, pktlen);
1033 m->b_wptr += pktlen;
1034
1035 wh = (struct ieee80211_frame *)m->b_rptr;
1036 ni = ieee80211_find_rxnode(ic, wh);
1037
1038 rssi = rt2661_get_rssi(sc, desc->rssi);
1039 /* send the frame to the 802.11 layer */
1040 (void) ieee80211_input(ic, m, ni, rssi + 95, 0);
1041
1042 sc->avg_rssi = (rssi + 7 * sc->avg_rssi) / 8;
1043
1044 /* node is no longer needed */
1045 ieee80211_free_node(ni);
1046 skip:
1047 desc->flags |= LE_32(RT2661_RX_BUSY);
1048
1049 (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl,
1050 ring->cur * RT2661_RX_DESC_SIZE,
1051 RT2661_RX_DESC_SIZE,
1052 DDI_DMA_SYNC_FORDEV);
1053
1054 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_rx_intr(): "
1055 "rx intr idx=%u\n", sc->rxq.cur);
1056 ring->cur = (ring->cur + 1) % RT2661_RX_RING_COUNT;
1057 }
1058 mutex_exit(&sc->sc_rxlock);
1059 }
1060
1061 /*ARGSUSED*/
1062 static uint_t
1063 rt2661_softintr(caddr_t data, caddr_t unused)
1064 {
1065 struct rt2661_softc *sc = (struct rt2661_softc *)data;
1066
1067 if (sc->sc_rx_pend) {
1068 sc->sc_rx_pend = 0;
1069 rt2661_rx_intr(sc);
1070 return (DDI_INTR_CLAIMED);
1071 }
1072 return (DDI_INTR_UNCLAIMED);
1073 }
1074
1075 static int
1076 rt2661_tx_cmd(struct rt2661_softc *sc, uint8_t cmd, uint16_t arg)
1077 {
1078 if (RT2661_READ(sc, RT2661_H2M_MAILBOX_CSR) & RT2661_H2M_BUSY)
1079 return (EIO); /* there is already a command pending */
1080
1081 RT2661_WRITE(sc, RT2661_H2M_MAILBOX_CSR,
1082 RT2661_H2M_BUSY | RT2661_TOKEN_NO_INTR << 16 | arg);
1083
1084 RT2661_WRITE(sc, RT2661_HOST_CMD_CSR, RT2661_KICK_CMD | cmd);
1085
1086 return (0);
1087 }
1088
1089 static void
1090 rt2661_mcu_wakeup(struct rt2661_softc *sc)
1091 {
1092 RT2661_WRITE(sc, RT2661_MAC_CSR11, 5 << 16);
1093
1094 RT2661_WRITE(sc, RT2661_SOFT_RESET_CSR, 0x7);
1095 RT2661_WRITE(sc, RT2661_IO_CNTL_CSR, 0x18);
1096 RT2661_WRITE(sc, RT2661_PCI_USEC_CSR, 0x20);
1097
1098 /* send wakeup command to MCU */
1099 (void) rt2661_tx_cmd(sc, RT2661_MCU_CMD_WAKEUP, 0);
1100 }
1101
1102 static void
1103 rt2661_mcu_cmd_intr(struct rt2661_softc *sc)
1104 {
1105 (void) RT2661_READ(sc, RT2661_M2H_CMD_DONE_CSR);
1106 RT2661_WRITE(sc, RT2661_M2H_CMD_DONE_CSR, 0xffffffff);
1107 }
1108
1109 /*ARGSUSED*/
1110 static uint_t
1111 rt2661_intr(caddr_t arg, caddr_t unused)
1112 {
1113 struct rt2661_softc *sc = (struct rt2661_softc *)arg;
1114 uint32_t r1, r2;
1115
1116 RT2661_GLOCK(sc);
1117
1118 if (!RT2661_IS_RUNNING(sc) || RT2661_IS_SUSPEND(sc)) {
1119 RT2661_GUNLOCK(sc);
1120 return (DDI_INTR_UNCLAIMED);
1121 }
1122
1123 r1 = RT2661_READ(sc, RT2661_INT_SOURCE_CSR);
1124 r2 = RT2661_READ(sc, RT2661_MCU_INT_SOURCE_CSR);
1125 if (r1 == 0 && r2 == 0) {
1126 RT2661_GUNLOCK(sc);
1127 return (DDI_INTR_UNCLAIMED); /* not for us */
1128 }
1129
1130 /* disable MAC and MCU interrupts */
1131 RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f);
1132 RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff);
1133
1134 /* acknowledge interrupts */
1135 RT2661_WRITE(sc, RT2661_INT_SOURCE_CSR, r1);
1136 RT2661_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, r2);
1137
1138 if (r1 & RT2661_MGT_DONE) {
1139 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1140 "RT2661_MGT_DONE\n");
1141 rt2661_tx_dma_intr(sc, &sc->mgtq);
1142 }
1143
1144 if (r1 & RT2661_RX_DONE) {
1145 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1146 "RT2661_RX_DONE\n");
1147 sc->sc_rx_pend = 1;
1148 (void) ddi_intr_trigger_softint(sc->sc_softintr_hdl, NULL);
1149 }
1150
1151 if (r1 & RT2661_TX0_DMA_DONE) {
1152 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1153 "RT2661_TX0_DMA_DONE\n");
1154 rt2661_tx_dma_intr(sc, &sc->txq[0]);
1155 }
1156
1157 if (r1 & RT2661_TX1_DMA_DONE) {
1158 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1159 "RT2661_TX1_DMA_DONE\n");
1160 rt2661_tx_dma_intr(sc, &sc->txq[1]);
1161 }
1162
1163 if (r1 & RT2661_TX2_DMA_DONE) {
1164 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1165 "RT2661_TX2_DMA_DONE\n");
1166 rt2661_tx_dma_intr(sc, &sc->txq[2]);
1167 }
1168
1169 if (r1 & RT2661_TX3_DMA_DONE) {
1170 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1171 "RT2661_TX3_DMA_DONE\n");
1172 rt2661_tx_dma_intr(sc, &sc->txq[3]);
1173 }
1174
1175 if (r1 & RT2661_TX_DONE) {
1176 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1177 "RT2661_TX_DONE\n");
1178 rt2661_tx_intr(sc);
1179 }
1180
1181 if (r2 & RT2661_MCU_CMD_DONE) {
1182 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1183 "RT2661_MCU_CMD_DONE\n");
1184 rt2661_mcu_cmd_intr(sc);
1185 }
1186
1187 if (r2 & RT2661_MCU_WAKEUP) {
1188 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1189 "RT2661_MCU_WAKEUP\n");
1190 rt2661_mcu_wakeup(sc);
1191 }
1192
1193 /* re-enable MAC and MCU interrupts */
1194 RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0x0000ff10);
1195 RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0);
1196
1197 RT2661_GUNLOCK(sc);
1198 return (RT2661_SUCCESS);
1199 }
1200
1201 /*
1202 * Retrieve the "Received Signal Strength Indicator" from the raw values
1203 * contained in Rx descriptors. The computation depends on which band the
1204 * frame was received. Correction values taken from the reference driver.
1205 */
1206 static int
1207 rt2661_get_rssi(struct rt2661_softc *sc, uint8_t raw)
1208 {
1209 int lna, agc, rssi;
1210
1211 lna = (raw >> 5) & 0x3;
1212 agc = raw & 0x1f;
1213
1214 rssi = 2 * agc;
1215
1216 if (IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan)) {
1217 rssi += sc->rssi_2ghz_corr;
1218
1219 if (lna == 1)
1220 rssi -= 64;
1221 else if (lna == 2)
1222 rssi -= 74;
1223 else if (lna == 3)
1224 rssi -= 90;
1225 } else {
1226 rssi += sc->rssi_5ghz_corr;
1227
1228 if (lna == 1)
1229 rssi -= 64;
1230 else if (lna == 2)
1231 rssi -= 86;
1232 else if (lna == 3)
1233 rssi -= 100;
1234 }
1235 return (rssi);
1236 }
1237
1238 /* quickly determine if a given rate is CCK or OFDM */
1239 #define RT2661_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
1240
1241 #define RT2661_ACK_SIZE 14 /* 10 + 4(FCS) */
1242 #define RT2661_CTS_SIZE 14 /* 10 + 4(FCS) */
1243
1244 #define RT2661_SIFS 10 /* us */
1245
1246 /*
1247 * Return the expected ack rate for a frame transmitted at rate `rate'.
1248 * XXX: this should depend on the destination node basic rate set.
1249 */
1250 static int
1251 rt2661_ack_rate(struct ieee80211com *ic, int rate)
1252 {
1253 switch (rate) {
1254 /* CCK rates */
1255 case 2:
1256 return (2);
1257 case 4:
1258 case 11:
1259 case 22:
1260 return ((ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate);
1261
1262 /* OFDM rates */
1263 case 12:
1264 case 18:
1265 return (12);
1266 case 24:
1267 case 36:
1268 return (24);
1269 case 48:
1270 case 72:
1271 case 96:
1272 case 108:
1273 return (48);
1274 }
1275
1276 /* default to 1Mbps */
1277 return (2);
1278 }
1279
1280 /*
1281 * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'.
1282 * The function automatically determines the operating mode depending on the
1283 * given rate. `flags' indicates whether short preamble is in use or not.
1284 */
1285 static uint16_t
1286 rt2661_txtime(int len, int rate, uint32_t flags)
1287 {
1288 uint16_t txtime;
1289
1290 if (RT2661_RATE_IS_OFDM(rate)) {
1291 /* IEEE Std 802.11a-1999, pp. 37 */
1292 txtime = (8 + 4 * len + 3 + rate - 1) / rate;
1293 txtime = 16 + 4 + 4 * txtime + 6;
1294 } else {
1295 /* IEEE Std 802.11b-1999, pp. 28 */
1296 txtime = (16 * len + rate - 1) / rate;
1297 if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE))
1298 txtime += 72 + 24;
1299 else
1300 txtime += 144 + 48;
1301 }
1302
1303 return (txtime);
1304 }
1305
1306 static uint8_t
1307 rt2661_plcp_signal(int rate)
1308 {
1309 switch (rate) {
1310 /* CCK rates (returned values are device-dependent) */
1311 case 2:
1312 return (0x0);
1313 case 4:
1314 return (0x1);
1315 case 11:
1316 return (0x2);
1317 case 22:
1318 return (0x3);
1319
1320 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
1321 case 12:
1322 return (0xb);
1323 case 18:
1324 return (0xf);
1325 case 24:
1326 return (0xa);
1327 case 36:
1328 return (0xe);
1329 case 48:
1330 return (0x9);
1331 case 72:
1332 return (0xd);
1333 case 96:
1334 return (0x8);
1335 case 108:
1336 return (0xc);
1337
1338 /* unsupported rates (should not get there) */
1339 default:
1340 return (0xff);
1341 }
1342 }
1343
1344 static void
1345 rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc,
1346 uint32_t flags, uint16_t xflags, int len, int rate, int ac)
1347 {
1348 struct ieee80211com *ic = &sc->sc_ic;
1349 uint16_t plcp_length;
1350 int remainder;
1351
1352 desc->flags = LE_32(flags);
1353 desc->flags |= LE_32(len << 16);
1354 desc->flags |= LE_32(RT2661_TX_BUSY | RT2661_TX_VALID);
1355
1356 desc->xflags = LE_16(xflags);
1357 desc->xflags |= LE_16(1 << 13);
1358
1359 desc->wme = LE_16(
1360 RT2661_QID(ac) |
1361 RT2661_AIFSN(2) |
1362 RT2661_LOGCWMIN(4) |
1363 RT2661_LOGCWMAX(10));
1364
1365 /*
1366 * Remember in which queue this frame was sent. This field is driver
1367 * private data only. It will be made available by the NIC in STA_CSR4
1368 * on Tx interrupts.
1369 */
1370 desc->qid = (uint8_t)ac;
1371
1372 /* setup PLCP fields */
1373 desc->plcp_signal = rt2661_plcp_signal(rate);
1374 desc->plcp_service = 4;
1375
1376 len += IEEE80211_CRC_LEN;
1377
1378 if (RT2661_RATE_IS_OFDM(rate)) {
1379 desc->flags |= LE_32(RT2661_TX_OFDM);
1380
1381 plcp_length = len & 0xfff;
1382 desc->plcp_length_hi = plcp_length >> 6;
1383 desc->plcp_length_lo = plcp_length & 0x3f;
1384 } else {
1385 plcp_length = (16 * len + rate - 1) / rate;
1386 if (rate == 22) {
1387 remainder = (16 * len) % 22;
1388 if (remainder != 0 && remainder < 7)
1389 desc->plcp_service |= RT2661_PLCP_LENGEXT;
1390 }
1391 desc->plcp_length_hi = plcp_length >> 8;
1392 desc->plcp_length_lo = plcp_length & 0xff;
1393
1394 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
1395 desc->plcp_signal |= 0x08;
1396 }
1397
1398 /* RT2x61 supports scatter with up to 5 segments */
1399 desc->len [0] = LE_16(len);
1400 }
1401
1402 static int
1403 rt2661_send(ieee80211com_t *ic, mblk_t *mp)
1404 {
1405 struct rt2661_softc *sc = (struct rt2661_softc *)ic;
1406 struct rt2661_tx_ring *ring;
1407 struct rt2661_tx_desc *desc;
1408 struct rt2661_tx_data *data;
1409 struct ieee80211_frame *wh;
1410 struct ieee80211_node *ni;
1411
1412 int err, off, rate;
1413 int mblen, pktlen;
1414 mblk_t *m, *m0;
1415 uint16_t dur;
1416 uint32_t flags = 0;
1417
1418 mutex_enter(&sc->sc_txlock);
1419 ring = &sc->txq[0];
1420 err = DDI_SUCCESS;
1421
1422 if (ring->queued > RT2661_TX_RING_COUNT - 8) {
1423 sc->sc_need_sched = 1;
1424 sc->sc_tx_nobuf++;
1425 err = ENOMEM;
1426 goto fail1;
1427 }
1428
1429 m = allocb(msgdsize(mp) + 32, BPRI_MED);
1430 if (m == NULL) {
1431 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_send():"
1432 "can't alloc mblk.\n");
1433 err = DDI_FAILURE;
1434 goto fail1;
1435 }
1436
1437 for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) {
1438 mblen = MBLKL(m0);
1439 (void) bcopy(m0->b_rptr, m->b_rptr + off, mblen);
1440 off += mblen;
1441 }
1442 m->b_wptr += off;
1443
1444 wh = (struct ieee80211_frame *)m->b_rptr;
1445 ni = ieee80211_find_txnode(ic, wh->i_addr1);
1446 if (ni == NULL) {
1447 err = DDI_FAILURE;
1448 sc->sc_tx_err++;
1449 goto fail2;
1450 }
1451
1452 (void) ieee80211_encap(ic, m, ni);
1453
1454 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1455 struct ieee80211_key *k;
1456 k = ieee80211_crypto_encap(ic, m);
1457 if (k == NULL) {
1458 sc->sc_tx_err++;
1459 err = DDI_FAILURE;
1460 goto fail3;
1461 }
1462 /* packet header may have moved, reset our local pointer */
1463 wh = (struct ieee80211_frame *)m->b_rptr;
1464 }
1465
1466 pktlen = msgdsize(m);
1467
1468 desc = &ring->desc[ring->cur];
1469 data = &ring->data[ring->cur];
1470 data->ni = ieee80211_ref_node(ni);
1471
1472 /* pickup a rate */
1473 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1474 /* multicast frames are sent at the lowest avail. rate */
1475 rate = ni->in_rates.ir_rates[0];
1476 } else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) {
1477 rate = ic->ic_sup_rates[ic->ic_curmode].
1478 ir_rates[ic->ic_fixed_rate];
1479 } else
1480 rate = ni->in_rates.ir_rates[ni->in_txrate];
1481 if (rate == 0)
1482 rate = 2; /* XXX should not happen */
1483 rate &= IEEE80211_RATE_VAL;
1484
1485 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1486 flags |= RT2661_TX_NEED_ACK;
1487
1488 dur = rt2661_txtime(RT2661_ACK_SIZE,
1489 rt2661_ack_rate(ic, rate), ic->ic_flags) + sc->sifs;
1490 *(uint16_t *)wh->i_dur = LE_16(dur);
1491 }
1492
1493 bcopy(m->b_rptr, data->buf, pktlen);
1494 rt2661_setup_tx_desc(sc, desc, flags, 0, pktlen, rate, 0);
1495
1496 (void) ddi_dma_sync(data->txdata_dma.dma_hdl,
1497 0, pktlen,
1498 DDI_DMA_SYNC_FORDEV);
1499
1500 (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
1501 ring->cur * RT2661_TX_DESC_SIZE,
1502 RT2661_TX_DESC_SIZE,
1503 DDI_DMA_SYNC_FORDEV);
1504
1505 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_send(): "
1506 "sending data frame len=%u idx=%u rate=%u\n",
1507 pktlen, ring->cur, rate);
1508
1509 /* kick Tx */
1510 ring->queued++;
1511 ring->cur = (ring->cur + 1) % RT2661_TX_RING_COUNT;
1512 RT2661_WRITE(sc, RT2661_TX_CNTL_CSR, 1 << 0);
1513
1514 ic->ic_stats.is_tx_frags++;
1515 ic->ic_stats.is_tx_bytes += pktlen;
1516 fail3:
1517 ieee80211_free_node(ni);
1518 fail2:
1519 freemsg(m);
1520 fail1:
1521 if (err == DDI_SUCCESS)
1522 freemsg(mp);
1523 mutex_exit(&sc->sc_txlock);
1524 return (err);
1525 }
1526
1527 /*ARGSUSED*/
1528 static int
1529 rt2661_mgmt_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
1530 {
1531 struct rt2661_softc *sc = (struct rt2661_softc *)ic;
1532 struct rt2661_tx_ring *ring;
1533 struct rt2661_tx_desc *desc;
1534 struct rt2661_tx_data *data;
1535 struct ieee80211_frame *wh;
1536 struct ieee80211_node *ni;
1537
1538 int err, off, rate;
1539 int mblen, pktlen;
1540 mblk_t *m, *m0;
1541 uint16_t dur;
1542 uint32_t flags = 0;
1543
1544 if ((!RT2661_IS_RUNNING(sc)) || RT2661_IS_SUSPEND(sc)) {
1545 err = ENXIO;
1546 goto fail1;
1547 }
1548
1549 ring = &sc->mgtq;
1550 err = DDI_SUCCESS;
1551
1552 if (ring->queued >= RT2661_MGT_RING_COUNT) {
1553 sc->sc_tx_nobuf++;
1554 err = ENOMEM;
1555 goto fail1;
1556 }
1557
1558 m = allocb(msgdsize(mp) + 32, BPRI_MED);
1559 if (m == NULL) {
1560 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_mgmt_send():"
1561 "can't alloc mblk.\n");
1562 err = DDI_FAILURE;
1563 goto fail1;
1564 }
1565
1566 for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) {
1567 mblen = MBLKL(m0);
1568 (void) bcopy(m0->b_rptr, m->b_rptr + off, mblen);
1569 off += mblen;
1570 }
1571 m->b_wptr += off;
1572
1573 wh = (struct ieee80211_frame *)m->b_rptr;
1574 ni = ieee80211_find_txnode(ic, wh->i_addr1);
1575 if (ni == NULL) {
1576 err = DDI_FAILURE;
1577 sc->sc_tx_err++;
1578 goto fail2;
1579 }
1580
1581 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1582 struct ieee80211_key *k;
1583 k = ieee80211_crypto_encap(ic, m);
1584 if (k == NULL) {
1585 sc->sc_tx_err++;
1586 err = DDI_FAILURE;
1587 goto fail3;
1588 }
1589 /* packet header may have moved, reset our local pointer */
1590 wh = (struct ieee80211_frame *)m->b_rptr;
1591 }
1592
1593 pktlen = msgdsize(m);
1594
1595 desc = &ring->desc[ring->cur];
1596 data = &ring->data[ring->cur];
1597 data->ni = ieee80211_ref_node(ni);
1598
1599 /* send mgt frames at the lowest available rate */
1600 rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
1601
1602 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1603 flags |= RT2661_TX_NEED_ACK;
1604
1605 dur = rt2661_txtime(RT2661_ACK_SIZE,
1606 rate, ic->ic_flags) + sc->sifs;
1607 *(uint16_t *)wh->i_dur = LE_16(dur);
1608
1609 /* tell hardware to add timestamp in probe responses */
1610 if ((wh->i_fc[0] &
1611 (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
1612 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
1613 flags |= RT2661_TX_TIMESTAMP;
1614 }
1615
1616 bcopy(m->b_rptr, data->buf, pktlen);
1617 rt2661_setup_tx_desc(sc, desc, flags, 0, pktlen, rate, RT2661_QID_MGT);
1618
1619 (void) ddi_dma_sync(data->txdata_dma.dma_hdl,
1620 0, pktlen,
1621 DDI_DMA_SYNC_FORDEV);
1622
1623 (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
1624 ring->cur * RT2661_TX_DESC_SIZE,
1625 RT2661_TX_DESC_SIZE,
1626 DDI_DMA_SYNC_FORDEV);
1627
1628 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_mgmt_send(): "
1629 "sending mgmt frame len=%u idx=%u rate=%u\n",
1630 pktlen, ring->cur, rate);
1631
1632 /* kick Tx */
1633 ring->queued++;
1634 ring->cur = (ring->cur + 1) % RT2661_MGT_RING_COUNT;
1635 RT2661_WRITE(sc, RT2661_TX_CNTL_CSR, RT2661_KICK_MGT);
1636
1637 ic->ic_stats.is_tx_frags++;
1638 ic->ic_stats.is_tx_bytes += pktlen;
1639
1640 fail3:
1641 ieee80211_free_node(ni);
1642 fail2:
1643 freemsg(m);
1644 fail1:
1645 freemsg(mp);
1646 return (err);
1647 }
1648
1649 static void
1650 rt2661_amrr_node_init(const struct rt2661_amrr *amrr,
1651 struct rt2661_amrr_node *amn)
1652 {
1653 amn->amn_success = 0;
1654 amn->amn_recovery = 0;
1655 amn->amn_txcnt = amn->amn_retrycnt = 0;
1656 amn->amn_success_threshold = amrr->amrr_min_success_threshold;
1657 }
1658
1659 static void
1660 rt2661_amrr_choose(struct rt2661_amrr *amrr, struct ieee80211_node *ni,
1661 struct rt2661_amrr_node *amn)
1662 {
1663 #define RV(rate) ((rate) & IEEE80211_RATE_VAL)
1664 #define is_success(amn) \
1665 ((amn)->amn_retrycnt < (amn)->amn_txcnt / 10)
1666 #define is_failure(amn) \
1667 ((amn)->amn_retrycnt > (amn)->amn_txcnt / 3)
1668 #define is_enough(amn) \
1669 ((amn)->amn_txcnt > 10)
1670 #define is_min_rate(ni) \
1671 ((ni)->in_txrate == 0)
1672 #define is_max_rate(ni) \
1673 ((ni)->in_txrate == (ni)->in_rates.ir_nrates - 1)
1674 #define increase_rate(ni) \
1675 ((ni)->in_txrate++)
1676 #define decrease_rate(ni) \
1677 ((ni)->in_txrate--)
1678 #define reset_cnt(amn) \
1679 { (amn)->amn_txcnt = (amn)->amn_retrycnt = 0; }
1680
1681 int need_change = 0;
1682
1683 if (is_success(amn) && is_enough(amn)) {
1684 amn->amn_success++;
1685 if (amn->amn_success >= amn->amn_success_threshold &&
1686 !is_max_rate(ni)) {
1687 amn->amn_recovery = 1;
1688 amn->amn_success = 0;
1689 increase_rate(ni);
1690 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_amrr_choose(): "
1691 "increase rate = %d, #tx = %d, #retries = %d\n",
1692 RV(ni->in_rates.ir_rates[ni->in_txrate]),
1693 amn->amn_txcnt, amn->amn_retrycnt);
1694 need_change = 1;
1695 } else
1696 amn->amn_recovery = 0;
1697 } else if (is_failure(amn)) {
1698 amn->amn_success = 0;
1699 if (!is_min_rate(ni)) {
1700 if (amn->amn_recovery) {
1701 amn->amn_success_threshold *= 2;
1702 if (amn->amn_success_threshold >
1703 amrr->amrr_max_success_threshold)
1704 amn->amn_success_threshold =
1705 amrr->amrr_max_success_threshold;
1706 } else {
1707 amn->amn_success_threshold =
1708 amrr->amrr_min_success_threshold;
1709 }
1710 decrease_rate(ni);
1711 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_amrr_choose(): "
1712 "decrease rate = %d, #tx = %d, #retries = %d\n",
1713 RV(ni->in_rates.ir_rates[ni->in_txrate]),
1714 amn->amn_txcnt, amn->amn_retrycnt);
1715 need_change = 1;
1716 }
1717 amn->amn_recovery = 0;
1718 }
1719
1720 if (is_enough(amn) || need_change)
1721 reset_cnt(amn);
1722 #undef RV
1723
1724 }
1725
1726 static void
1727 rt2661_update_promisc(struct rt2661_softc *sc)
1728 {
1729 uint32_t tmp;
1730
1731 tmp = RT2661_READ(sc, RT2661_TXRX_CSR0);
1732
1733 tmp &= ~RT2661_DROP_NOT_TO_ME;
1734 if (!(sc->sc_rcr & RT2661_RCR_PROMISC))
1735 tmp |= RT2661_DROP_NOT_TO_ME;
1736
1737 RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp);
1738 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_update_promisc(): "
1739 "%s promiscuous mode\n",
1740 (sc->sc_rcr & RT2661_RCR_PROMISC) ? "entering" : "leaving");
1741 }
1742
1743 static void
1744 rt2661_updateslot(struct ieee80211com *ic, int onoff)
1745 {
1746 struct rt2661_softc *sc = (struct rt2661_softc *)ic;
1747 uint8_t slottime;
1748 uint32_t tmp;
1749
1750 slottime = (onoff ? 9 : 20);
1751
1752 tmp = RT2661_READ(sc, RT2661_MAC_CSR9);
1753 tmp = (tmp & ~0xff) | slottime;
1754 RT2661_WRITE(sc, RT2661_MAC_CSR9, tmp);
1755
1756 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_updateslot(): "
1757 "setting slot time to %uus\n", slottime);
1758 }
1759
1760 static void
1761 rt2661_set_slottime(struct rt2661_softc *sc)
1762 {
1763 struct ieee80211com *ic = &sc->sc_ic;
1764 uint8_t slottime;
1765 uint32_t tmp;
1766
1767 slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
1768
1769 tmp = RT2661_READ(sc, RT2661_MAC_CSR9);
1770 tmp = (tmp & ~0xff) | slottime;
1771 RT2661_WRITE(sc, RT2661_MAC_CSR9, tmp);
1772
1773 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_set_slottime(): "
1774 "setting slot time to %uus\n", slottime);
1775 }
1776
1777
1778 /*
1779 * Enable multi-rate retries for frames sent at OFDM rates.
1780 * In 802.11b/g mode, allow fallback to CCK rates.
1781 */
1782 static void
1783 rt2661_enable_mrr(struct rt2661_softc *sc)
1784 {
1785 struct ieee80211com *ic = &sc->sc_ic;
1786 uint32_t tmp;
1787
1788 tmp = RT2661_READ(sc, RT2661_TXRX_CSR4);
1789
1790 tmp &= ~RT2661_MRR_CCK_FALLBACK;
1791 if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
1792 tmp |= RT2661_MRR_CCK_FALLBACK;
1793 tmp |= RT2661_MRR_ENABLED;
1794
1795 RT2661_WRITE(sc, RT2661_TXRX_CSR4, tmp);
1796 }
1797
1798 static void
1799 rt2661_set_txpreamble(struct rt2661_softc *sc)
1800 {
1801 uint32_t tmp;
1802
1803 tmp = RT2661_READ(sc, RT2661_TXRX_CSR4);
1804
1805 tmp &= ~RT2661_SHORT_PREAMBLE;
1806 if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE)
1807 tmp |= RT2661_SHORT_PREAMBLE;
1808
1809 RT2661_WRITE(sc, RT2661_TXRX_CSR4, tmp);
1810 }
1811
1812 static void
1813 rt2661_set_basicrates(struct rt2661_softc *sc)
1814 {
1815 struct ieee80211com *ic = &sc->sc_ic;
1816
1817 /* update basic rate set */
1818 if (ic->ic_curmode == IEEE80211_MODE_11B) {
1819 /* 11b basic rates: 1, 2Mbps */
1820 RT2661_WRITE(sc, RT2661_TXRX_CSR5, 0x3);
1821 } else if (ic->ic_curmode == IEEE80211_MODE_11A) {
1822 /* 11a basic rates: 6, 12, 24Mbps */
1823 RT2661_WRITE(sc, RT2661_TXRX_CSR5, 0x150);
1824 } else {
1825 /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
1826 RT2661_WRITE(sc, RT2661_TXRX_CSR5, 0xf);
1827 }
1828 }
1829
1830 static void
1831 rt2661_set_bssid(struct rt2661_softc *sc, const uint8_t *bssid)
1832 {
1833 uint32_t tmp;
1834
1835 tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
1836 RT2661_WRITE(sc, RT2661_MAC_CSR4, tmp);
1837
1838 tmp = bssid[4] | bssid[5] << 8 | RT2661_ONE_BSSID << 16;
1839 RT2661_WRITE(sc, RT2661_MAC_CSR5, tmp);
1840 }
1841
1842 /*
1843 * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
1844 * and HostAP operating modes.
1845 */
1846 static void
1847 rt2661_enable_tsf_sync(struct rt2661_softc *sc)
1848 {
1849 struct ieee80211com *ic = &sc->sc_ic;
1850 uint32_t tmp;
1851
1852 tmp = RT2661_READ(sc, RT2661_TXRX_CSR9) & 0xff000000;
1853
1854 /* set beacon interval (in 1/16ms unit) */
1855 tmp |= ic->ic_bss->in_intval * 16;
1856
1857 tmp |= RT2661_TSF_TICKING | RT2661_ENABLE_TBTT;
1858 if (ic->ic_opmode == IEEE80211_M_STA)
1859 tmp |= RT2661_TSF_MODE(1);
1860
1861 RT2661_WRITE(sc, RT2661_TXRX_CSR9, tmp);
1862 }
1863
1864
1865 static void
1866 rt2661_next_scan(void *arg)
1867 {
1868 struct rt2661_softc *sc = arg;
1869 struct ieee80211com *ic = &sc->sc_ic;
1870
1871 if (ic->ic_state == IEEE80211_S_SCAN)
1872 (void) ieee80211_next_scan(ic);
1873 }
1874
1875 static void
1876 rt2661_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni)
1877 {
1878 struct rt2661_softc *sc = (struct rt2661_softc *)ic;
1879 int i;
1880
1881 rt2661_amrr_node_init(&sc->amrr, &((struct rt2661_node *)ni)->amn);
1882
1883 /* set rate to some reasonable initial value */
1884 i = ni->in_rates.ir_nrates - 1;
1885 while (i > 0 && ((ni->in_rates.ir_rates[i] & IEEE80211_RATE_VAL) > 72))
1886 i--;
1887
1888 ni->in_txrate = i;
1889 }
1890
1891 static void
1892 rt2661_iter_func(void *arg, struct ieee80211_node *ni)
1893 {
1894 struct rt2661_softc *sc = arg;
1895 struct rt2661_node *rn = (struct rt2661_node *)ni;
1896
1897 rt2661_amrr_choose(&sc->amrr, ni, &rn->amn);
1898
1899 }
1900
1901 /*
1902 * Dynamically tune Rx sensitivity (BBP register 17) based on average RSSI and
1903 * false CCA count. This function is called periodically (every seconds) when
1904 * in the RUN state. Values taken from the reference driver.
1905 */
1906 static void
1907 rt2661_rx_tune(struct rt2661_softc *sc)
1908 {
1909 uint8_t bbp17;
1910 uint16_t cca;
1911 int lo, hi, dbm;
1912
1913 /*
1914 * Tuning range depends on operating band and on the presence of an
1915 * external low-noise amplifier.
1916 */
1917 lo = 0x20;
1918 if (IEEE80211_IS_CHAN_5GHZ(sc->sc_curchan))
1919 lo += 0x08;
1920 if ((IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) && sc->ext_2ghz_lna) ||
1921 (IEEE80211_IS_CHAN_5GHZ(sc->sc_curchan) && sc->ext_5ghz_lna))
1922 lo += 0x10;
1923 hi = lo + 0x20;
1924
1925 dbm = sc->avg_rssi;
1926 /* retrieve false CCA count since last call (clear on read) */
1927 cca = RT2661_READ(sc, RT2661_STA_CSR1) & 0xffff;
1928
1929 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_rx_tune(): "
1930 "RSSI=%ddBm false CCA=%d\n", dbm, cca);
1931
1932 if (dbm < -74) {
1933 /* very bad RSSI, tune using false CCA count */
1934 bbp17 = sc->bbp17; /* current value */
1935
1936 hi -= 2 * (-74 - dbm);
1937 if (hi < lo)
1938 hi = lo;
1939
1940 if (bbp17 > hi)
1941 bbp17 = (uint8_t)hi;
1942 else if (cca > 512)
1943 bbp17 = (uint8_t)min(bbp17 + 1, hi);
1944 else if (cca < 100)
1945 bbp17 = (uint8_t)max(bbp17 - 1, lo);
1946
1947 } else if (dbm < -66) {
1948 bbp17 = lo + 0x08;
1949 } else if (dbm < -58) {
1950 bbp17 = lo + 0x10;
1951 } else if (dbm < -35) {
1952 bbp17 = (uint8_t)hi;
1953 } else { /* very good RSSI >= -35dBm */
1954 bbp17 = 0x60; /* very low sensitivity */
1955 }
1956
1957 if (bbp17 != sc->bbp17) {
1958 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_tune(): "
1959 "BBP17 %x->%x\n", sc->bbp17, bbp17);
1960 rt2661_bbp_write(sc, 17, bbp17);
1961 sc->bbp17 = bbp17;
1962 }
1963 }
1964
1965 /*
1966 * This function is called periodically (every 500ms) in RUN state to update
1967 * various settings like rate control statistics or Rx sensitivity.
1968 */
1969 static void
1970 rt2661_updatestats(void *arg)
1971 {
1972 struct rt2661_softc *sc = arg;
1973 struct ieee80211com *ic = &sc->sc_ic;
1974
1975 if (ic->ic_opmode == IEEE80211_M_STA)
1976 rt2661_iter_func(sc, ic->ic_bss);
1977 else
1978 ieee80211_iterate_nodes(&ic->ic_sta, rt2661_iter_func, arg);
1979
1980 /* update rx sensitivity every 1 sec */
1981 if (++sc->ncalls & 1)
1982 rt2661_rx_tune(sc);
1983
1984 sc->sc_rssadapt_id = timeout(rt2661_updatestats, (void *)sc,
1985 drv_usectohz(200 * 1000));
1986 }
1987
1988 static int
1989 rt2661_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1990 {
1991 struct rt2661_softc *sc = (struct rt2661_softc *)ic;
1992 enum ieee80211_state ostate;
1993 struct ieee80211_node *ni;
1994 uint32_t tmp;
1995 int err;
1996
1997 RT2661_GLOCK(sc);
1998
1999 ostate = ic->ic_state;
2000 sc->sc_ostate = ostate;
2001
2002 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt26661_newstate(): "
2003 "%x -> %x\n", ostate, nstate);
2004
2005 if (sc->sc_scan_id != 0) {
2006 (void) untimeout(sc->sc_scan_id);
2007 sc->sc_scan_id = 0;
2008 }
2009
2010 if (sc->sc_rssadapt_id) {
2011 (void) untimeout(sc->sc_rssadapt_id);
2012 sc->sc_rssadapt_id = 0;
2013 }
2014
2015 switch (nstate) {
2016 case IEEE80211_S_INIT:
2017 if (ostate == IEEE80211_S_RUN) {
2018 /* abort TSF synchronization */
2019 tmp = RT2661_READ(sc, RT2661_TXRX_CSR9);
2020 RT2661_WRITE(sc, RT2661_TXRX_CSR9, tmp & ~0x00ffffff);
2021 }
2022 break;
2023 case IEEE80211_S_SCAN:
2024 rt2661_set_chan(sc, ic->ic_curchan);
2025 sc->sc_scan_id = timeout(rt2661_next_scan, (void *)sc,
2026 drv_usectohz(200000));
2027 break;
2028 case IEEE80211_S_AUTH:
2029 case IEEE80211_S_ASSOC:
2030 rt2661_set_chan(sc, ic->ic_curchan);
2031 break;
2032 case IEEE80211_S_RUN:
2033 rt2661_set_chan(sc, ic->ic_curchan);
2034
2035 ni = ic->ic_bss;
2036 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
2037 rt2661_set_slottime(sc);
2038 rt2661_enable_mrr(sc);
2039 rt2661_set_txpreamble(sc);
2040 rt2661_set_basicrates(sc);
2041 rt2661_set_bssid(sc, ni->in_bssid);
2042 }
2043
2044 if (ic->ic_opmode == IEEE80211_M_STA) {
2045 /* fake a join to init the tx rate */
2046 rt2661_newassoc(ic, ni);
2047 }
2048
2049 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
2050 sc->ncalls = 0;
2051 sc->avg_rssi = -95; /* reset EMA */
2052 sc->sc_rssadapt_id = timeout(rt2661_updatestats,
2053 (void *)sc, drv_usectohz(200 * 1000));
2054 rt2661_enable_tsf_sync(sc);
2055 }
2056 break;
2057 default:
2058 break;
2059 }
2060
2061 RT2661_GUNLOCK(sc);
2062
2063 err = sc->sc_newstate(ic, nstate, arg);
2064 return (err);
2065 }
2066
2067 /*ARGSUSED*/
2068 static struct ieee80211_node *
2069 rt2661_node_alloc(ieee80211com_t *ic)
2070 {
2071 struct rt2661_node *rn;
2072
2073 rn = kmem_zalloc(sizeof (struct rt2661_node), KM_SLEEP);
2074 return ((rn != NULL) ? &rn->ni : NULL);
2075 }
2076
2077 static void
2078 rt2661_node_free(struct ieee80211_node *in)
2079 {
2080 struct ieee80211com *ic = in->in_ic;
2081
2082 ic->ic_node_cleanup(in);
2083 if (in->in_wpa_ie != NULL)
2084 ieee80211_free(in->in_wpa_ie);
2085 kmem_free(in, sizeof (struct rt2661_node));
2086 }
2087
2088 static void
2089 rt2661_stop_locked(struct rt2661_softc *sc)
2090 {
2091 uint32_t tmp;
2092
2093 if (RT2661_IS_RUNNING(sc)) {
2094 sc->sc_tx_timer = 0;
2095
2096 /* abort Tx (for all 5 Tx rings) */
2097 RT2661_WRITE(sc, RT2661_TX_CNTL_CSR, 0x1f << 16);
2098
2099 /* disable Rx (value remains after reset!) */
2100 tmp = RT2661_READ(sc, RT2661_TXRX_CSR0);
2101 RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX);
2102
2103 /* reset ASIC */
2104 RT2661_WRITE(sc, RT2661_MAC_CSR1, 3);
2105 RT2661_WRITE(sc, RT2661_MAC_CSR1, 0);
2106
2107 /* disable interrupts */
2108 RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f);
2109 RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff);
2110
2111 /* clear any pending interrupt */
2112 RT2661_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff);
2113 RT2661_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, 0xffffffff);
2114
2115 /* reset Tx and Rx rings */
2116 rt2661_reset_tx_ring(sc, &sc->txq[0]);
2117 rt2661_reset_tx_ring(sc, &sc->txq[1]);
2118 rt2661_reset_tx_ring(sc, &sc->txq[2]);
2119 rt2661_reset_tx_ring(sc, &sc->txq[3]);
2120 rt2661_reset_tx_ring(sc, &sc->mgtq);
2121 rt2661_reset_rx_ring(sc, &sc->rxq);
2122 }
2123 }
2124
2125 static void
2126 rt2661_set_macaddr(struct rt2661_softc *sc, const uint8_t *addr)
2127 {
2128 uint32_t tmp;
2129
2130 tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
2131 RT2661_WRITE(sc, RT2661_MAC_CSR2, tmp);
2132
2133 tmp = addr[4] | addr[5] << 8 | 0xff << 16;
2134 RT2661_WRITE(sc, RT2661_MAC_CSR3, tmp);
2135 }
2136
2137 static uint8_t
2138 rt2661_bbp_read(struct rt2661_softc *sc, uint8_t reg)
2139 {
2140 uint32_t val;
2141 int ntries;
2142
2143 for (ntries = 0; ntries < 100; ntries++) {
2144 if (!(RT2661_READ(sc, RT2661_PHY_CSR3) & RT2661_BBP_BUSY))
2145 break;
2146 DELAY(1);
2147 }
2148 if (ntries == 100) {
2149 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_read(): "
2150 "could not read from BBP\n");
2151 return (0);
2152 }
2153
2154 val = RT2661_BBP_BUSY | RT2661_BBP_READ | reg << 8;
2155 RT2661_WRITE(sc, RT2661_PHY_CSR3, val);
2156
2157 for (ntries = 0; ntries < 100; ntries++) {
2158 val = RT2661_READ(sc, RT2661_PHY_CSR3);
2159 if (!(val & RT2661_BBP_BUSY))
2160 return (val & 0xff);
2161 DELAY(1);
2162 }
2163
2164 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_read(): "
2165 "could not read from BBP\n");
2166 return (0);
2167 }
2168
2169 static int
2170 rt2661_bbp_init(struct rt2661_softc *sc)
2171 {
2172 #define N(a) (sizeof (a) / sizeof ((a)[0]))
2173
2174 int i, ntries;
2175 uint8_t val;
2176
2177 /* wait for BBP to be ready */
2178 for (ntries = 0; ntries < 100; ntries++) {
2179 val = rt2661_bbp_read(sc, 0);
2180 if (val != 0 && val != 0xff)
2181 break;
2182 DELAY(100);
2183 }
2184 if (ntries == 100) {
2185 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_init(): "
2186 "timeout waiting for BBP\n");
2187 return (RT2661_FAILURE);
2188 }
2189
2190 /* initialize BBP registers to default values */
2191 for (i = 0; i < N(rt2661_def_bbp); i++) {
2192 rt2661_bbp_write(sc, rt2661_def_bbp[i].reg,
2193 rt2661_def_bbp[i].val);
2194 }
2195
2196 /* write vendor-specific BBP values (from EEPROM) */
2197 for (i = 0; i < 16; i++) {
2198 if (sc->bbp_prom[i].reg == 0)
2199 continue;
2200 rt2661_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
2201 }
2202
2203 return (RT2661_SUCCESS);
2204 #undef N
2205 }
2206
2207 static void
2208 rt2661_bbp_write(struct rt2661_softc *sc, uint8_t reg, uint8_t val)
2209 {
2210 uint32_t tmp;
2211 int ntries;
2212
2213 for (ntries = 0; ntries < 100; ntries++) {
2214 if (!(RT2661_READ(sc, RT2661_PHY_CSR3) & RT2661_BBP_BUSY))
2215 break;
2216 DELAY(1);
2217 }
2218 if (ntries == 100) {
2219 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_write(): "
2220 "could not write to BBP\n");
2221 return;
2222 }
2223
2224 tmp = RT2661_BBP_BUSY | (reg & 0x7f) << 8 | val;
2225 RT2661_WRITE(sc, RT2661_PHY_CSR3, tmp);
2226
2227 RWD_DEBUG(RT2661_DBG_HW, "rwd: rt2661_bbp_write(): "
2228 "BBP R%u <- 0x%02x\n", reg, val);
2229 }
2230
2231 /*
2232 * Reprogram MAC/BBP to switch to a new band. Values taken from the reference
2233 * driver.
2234 */
2235 static void
2236 rt2661_select_band(struct rt2661_softc *sc, struct ieee80211_channel *c)
2237 {
2238 uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
2239 uint32_t tmp;
2240
2241 /* update all BBP registers that depend on the band */
2242 bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c;
2243 bbp35 = 0x50; bbp97 = 0x48; bbp98 = 0x48;
2244 if (IEEE80211_IS_CHAN_5GHZ(c)) {
2245 bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c;
2246 bbp35 += 0x10; bbp97 += 0x10; bbp98 += 0x10;
2247 }
2248 if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
2249 (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
2250 bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
2251 }
2252
2253 sc->bbp17 = bbp17;
2254 rt2661_bbp_write(sc, 17, bbp17);
2255 rt2661_bbp_write(sc, 96, bbp96);
2256 rt2661_bbp_write(sc, 104, bbp104);
2257
2258 if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
2259 (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
2260 rt2661_bbp_write(sc, 75, 0x80);
2261 rt2661_bbp_write(sc, 86, 0x80);
2262 rt2661_bbp_write(sc, 88, 0x80);
2263 }
2264
2265 rt2661_bbp_write(sc, 35, bbp35);
2266 rt2661_bbp_write(sc, 97, bbp97);
2267 rt2661_bbp_write(sc, 98, bbp98);
2268
2269 tmp = RT2661_READ(sc, RT2661_PHY_CSR0);
2270 tmp &= ~(RT2661_PA_PE_2GHZ | RT2661_PA_PE_5GHZ);
2271 if (IEEE80211_IS_CHAN_2GHZ(c))
2272 tmp |= RT2661_PA_PE_2GHZ;
2273 else
2274 tmp |= RT2661_PA_PE_5GHZ;
2275 RT2661_WRITE(sc, RT2661_PHY_CSR0, tmp);
2276
2277 /* 802.11a uses a 16 microseconds short interframe space */
2278 sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10;
2279 }
2280
2281 static void
2282 rt2661_select_antenna(struct rt2661_softc *sc)
2283 {
2284 uint8_t bbp4, bbp77;
2285 uint32_t tmp;
2286
2287 bbp4 = rt2661_bbp_read(sc, 4);
2288 bbp77 = rt2661_bbp_read(sc, 77);
2289
2290 /* TBD */
2291
2292 /* make sure Rx is disabled before switching antenna */
2293 tmp = RT2661_READ(sc, RT2661_TXRX_CSR0);
2294 RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX);
2295
2296 rt2661_bbp_write(sc, 4, bbp4);
2297 rt2661_bbp_write(sc, 77, bbp77);
2298
2299 /* restore Rx filter */
2300 RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp);
2301 }
2302
2303 static void
2304 rt2661_rf_write(struct rt2661_softc *sc, uint8_t reg, uint32_t val)
2305 {
2306 uint32_t tmp;
2307 int ntries;
2308
2309 for (ntries = 0; ntries < 100; ntries++) {
2310 if (!(RT2661_READ(sc, RT2661_PHY_CSR4) & RT2661_RF_BUSY))
2311 break;
2312 DELAY(1);
2313 }
2314 if (ntries == 100) {
2315 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rf_write(): "
2316 "could not write to RF\n");
2317 return;
2318 }
2319
2320 tmp = RT2661_RF_BUSY | RT2661_RF_21BIT | (val & 0x1fffff) << 2 |
2321 (reg & 3);
2322 RT2661_WRITE(sc, RT2661_PHY_CSR4, tmp);
2323
2324 /* remember last written value in sc */
2325 sc->rf_regs[reg] = val;
2326
2327 RWD_DEBUG(RT2661_DBG_FW, "rwd: rt2661_rf_write(): "
2328 "RF R[%u] <- 0x%05x\n", reg & 3, val & 0x1fffff);
2329 }
2330
2331 static void
2332 rt2661_set_chan(struct rt2661_softc *sc, struct ieee80211_channel *c)
2333 {
2334 struct ieee80211com *ic = &sc->sc_ic;
2335 const struct rfprog *rfprog;
2336 uint8_t bbp3, bbp94 = RT2661_BBPR94_DEFAULT;
2337 int8_t power;
2338 uint_t i, chan;
2339
2340 chan = ieee80211_chan2ieee(ic, c);
2341 if (chan == 0 || chan == IEEE80211_CHAN_ANY)
2342 return;
2343
2344 /* select the appropriate RF settings based on what EEPROM says */
2345 rfprog = (sc->rfprog == 0) ? rt2661_rf5225_1 : rt2661_rf5225_2;
2346
2347 /* find the settings for this channel (we know it exists) */
2348 i = 0;
2349 while (rfprog[i].chan != chan)
2350 i++;
2351
2352 power = sc->txpow[i];
2353 if (power < 0) {
2354 bbp94 += power;
2355 power = 0;
2356 } else if (power > 31) {
2357 bbp94 += power - 31;
2358 power = 31;
2359 }
2360
2361 /*
2362 * If we are switching from the 2GHz band to the 5GHz band or
2363 * vice-versa, BBP registers need to be reprogrammed.
2364 */
2365 if (ic->ic_flags != sc->sc_curchan->ich_flags) {
2366 rt2661_select_band(sc, c);
2367 rt2661_select_antenna(sc);
2368 }
2369 sc->sc_curchan = c;
2370
2371 rt2661_rf_write(sc, RT2661_RF1, rfprog[i].r1);
2372 rt2661_rf_write(sc, RT2661_RF2, rfprog[i].r2);
2373 rt2661_rf_write(sc, RT2661_RF3, rfprog[i].r3 | power << 7);
2374 rt2661_rf_write(sc, RT2661_RF4, rfprog[i].r4 | sc->rffreq << 10);
2375
2376 DELAY(200);
2377
2378 rt2661_rf_write(sc, RT2661_RF1, rfprog[i].r1);
2379 rt2661_rf_write(sc, RT2661_RF2, rfprog[i].r2);
2380 rt2661_rf_write(sc, RT2661_RF3, rfprog[i].r3 | power << 7 | 1);
2381 rt2661_rf_write(sc, RT2661_RF4, rfprog[i].r4 | sc->rffreq << 10);
2382
2383 DELAY(200);
2384
2385 rt2661_rf_write(sc, RT2661_RF1, rfprog[i].r1);
2386 rt2661_rf_write(sc, RT2661_RF2, rfprog[i].r2);
2387 rt2661_rf_write(sc, RT2661_RF3, rfprog[i].r3 | power << 7);
2388 rt2661_rf_write(sc, RT2661_RF4, rfprog[i].r4 | sc->rffreq << 10);
2389
2390 /* enable smart mode for MIMO-capable RFs */
2391 bbp3 = rt2661_bbp_read(sc, 3);
2392
2393 bbp3 &= ~RT2661_SMART_MODE;
2394 if (sc->rf_rev == RT2661_RF_5325 || sc->rf_rev == RT2661_RF_2529)
2395 bbp3 |= RT2661_SMART_MODE;
2396
2397 rt2661_bbp_write(sc, 3, bbp3);
2398
2399 if (bbp94 != RT2661_BBPR94_DEFAULT)
2400 rt2661_bbp_write(sc, 94, bbp94);
2401
2402 /* 5GHz radio needs a 1ms delay here */
2403 if (IEEE80211_IS_CHAN_5GHZ(c))
2404 DELAY(1000);
2405 }
2406
2407 static int
2408 rt2661_init(struct rt2661_softc *sc)
2409 {
2410 #define N(a) (sizeof (a) / sizeof ((a)[0]))
2411
2412 struct ieee80211com *ic = &sc->sc_ic;
2413 uint32_t tmp, sta[3], *fptr;
2414 int i, err, off, ntries;
2415
2416 RT2661_GLOCK(sc);
2417
2418 rt2661_stop_locked(sc);
2419
2420 if (!RT2661_IS_FWLOADED(sc)) {
2421 err = rt2661_load_microcode(sc, ucode, usize);
2422 if (err != RT2661_SUCCESS) {
2423 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2424 "could not load 8051 microcode\n");
2425 return (DDI_FAILURE);
2426 }
2427 sc->sc_flags |= RT2661_F_FWLOADED;
2428 }
2429
2430 /* initialize Tx rings */
2431 RT2661_WRITE(sc, RT2661_AC1_BASE_CSR, sc->txq[1].paddr);
2432 RT2661_WRITE(sc, RT2661_AC0_BASE_CSR, sc->txq[0].paddr);
2433 RT2661_WRITE(sc, RT2661_AC2_BASE_CSR, sc->txq[2].paddr);
2434 RT2661_WRITE(sc, RT2661_AC3_BASE_CSR, sc->txq[3].paddr);
2435
2436 /* initialize Mgt ring */
2437 RT2661_WRITE(sc, RT2661_MGT_BASE_CSR, sc->mgtq.paddr);
2438
2439 /* initialize Rx ring */
2440 RT2661_WRITE(sc, RT2661_RX_BASE_CSR, sc->rxq.paddr);
2441
2442 /* initialize Tx rings sizes */
2443 RT2661_WRITE(sc, RT2661_TX_RING_CSR0,
2444 RT2661_TX_RING_COUNT << 24 |
2445 RT2661_TX_RING_COUNT << 16 |
2446 RT2661_TX_RING_COUNT << 8 |
2447 RT2661_TX_RING_COUNT);
2448
2449 RT2661_WRITE(sc, RT2661_TX_RING_CSR1,
2450 RT2661_TX_DESC_WSIZE << 16 |
2451 RT2661_TX_RING_COUNT << 8 |
2452 RT2661_MGT_RING_COUNT);
2453
2454 /* initialize Rx rings */
2455 RT2661_WRITE(sc, RT2661_RX_RING_CSR,
2456 RT2661_RX_DESC_BACK << 16 |
2457 RT2661_RX_DESC_WSIZE << 8 |
2458 RT2661_RX_RING_COUNT);
2459
2460 /* XXX: some magic here */
2461 RT2661_WRITE(sc, RT2661_TX_DMA_DST_CSR, 0xaa);
2462
2463 /* load base addresses of all 5 Tx rings (4 data + 1 mgt) */
2464 RT2661_WRITE(sc, RT2661_LOAD_TX_RING_CSR, 0x1f);
2465
2466 /* load base address of Rx ring */
2467 RT2661_WRITE(sc, RT2661_RX_CNTL_CSR, 2);
2468
2469 /* initialize MAC registers to default values */
2470 for (i = 0; i < N(rt2661_def_mac); i++)
2471 RT2661_WRITE(sc, rt2661_def_mac[i].reg, rt2661_def_mac[i].val);
2472
2473 rt2661_set_macaddr(sc, ic->ic_macaddr);
2474
2475 /* set host ready */
2476 RT2661_WRITE(sc, RT2661_MAC_CSR1, 3);
2477 RT2661_WRITE(sc, RT2661_MAC_CSR1, 0);
2478
2479 /* wait for BBP/RF to wakeup */
2480 for (ntries = 0; ntries < 1000; ntries++) {
2481 if (RT2661_READ(sc, RT2661_MAC_CSR12) & 8)
2482 break;
2483 DELAY(1000);
2484 }
2485 if (ntries == 1000) {
2486 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2487 "timeout waiting for BBP/RF to wakeup\n");
2488 rt2661_stop_locked(sc);
2489 RT2661_GUNLOCK(sc);
2490 return (DDI_FAILURE);
2491 }
2492
2493 if (rt2661_bbp_init(sc) != RT2661_SUCCESS) {
2494 rt2661_stop_locked(sc);
2495 RT2661_GUNLOCK(sc);
2496 return (DDI_FAILURE);
2497 }
2498
2499 /* select default channel */
2500 sc->sc_curchan = ic->ic_bss->in_chan = ic->ic_curchan;
2501 rt2661_select_band(sc, sc->sc_curchan);
2502 rt2661_select_antenna(sc);
2503 rt2661_set_chan(sc, sc->sc_curchan);
2504
2505 /* update Rx filter */
2506 tmp = RT2661_READ(sc, RT2661_TXRX_CSR0) & 0xffff;
2507
2508 tmp |= RT2661_DROP_PHY_ERROR | RT2661_DROP_CRC_ERROR;
2509 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
2510 tmp |= RT2661_DROP_CTL | RT2661_DROP_VER_ERROR |
2511 RT2661_DROP_ACKCTS;
2512 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
2513 tmp |= RT2661_DROP_TODS;
2514 if (!(sc->sc_rcr & RT2661_RCR_PROMISC))
2515 tmp |= RT2661_DROP_NOT_TO_ME;
2516 }
2517
2518 RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp);
2519
2520 /* clear STA registers */
2521 off = RT2661_STA_CSR0;
2522 fptr = sta;
2523 for (i = 0; i < N(sta); i++) {
2524 *fptr = RT2661_MEM_READ1(sc, off++);
2525 }
2526
2527 /* initialize ASIC */
2528 RT2661_WRITE(sc, RT2661_MAC_CSR1, 4);
2529
2530 /* clear any pending interrupt */
2531 RT2661_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff);
2532
2533 /* enable interrupts */
2534 RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0x0000ff10);
2535 RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0);
2536
2537 /* kick Rx */
2538 RT2661_WRITE(sc, RT2661_RX_CNTL_CSR, 1);
2539 RT2661_GUNLOCK(sc);
2540
2541 #undef N
2542 return (DDI_SUCCESS);
2543 }
2544
2545 static void
2546 rt2661_stop(struct rt2661_softc *sc)
2547 {
2548 if (!RT2661_IS_FASTREBOOT(sc))
2549 RT2661_GLOCK(sc);
2550 rt2661_stop_locked(sc);
2551 if (!RT2661_IS_FASTREBOOT(sc))
2552 RT2661_GUNLOCK(sc);
2553 }
2554
2555 static int
2556 rt2661_m_start(void *arg)
2557 {
2558 struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2559 struct ieee80211com *ic = &sc->sc_ic;
2560 int err;
2561
2562 err = rt2661_init(sc);
2563 if (err != DDI_SUCCESS) {
2564 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_m_start():"
2565 "Hardware initialization failed\n");
2566 goto fail1;
2567 }
2568
2569 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2570
2571 RT2661_GLOCK(sc);
2572 sc->sc_flags |= RT2661_F_RUNNING;
2573 RT2661_GUNLOCK(sc);
2574
2575 return (DDI_SUCCESS);
2576 fail1:
2577 rt2661_stop(sc);
2578 return (err);
2579 }
2580
2581 static void
2582 rt2661_m_stop(void *arg)
2583 {
2584 struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2585
2586 (void) rt2661_stop(sc);
2587
2588 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
2589
2590 RT2661_GLOCK(sc);
2591 sc->sc_flags &= ~RT2661_F_RUNNING;
2592 RT2661_GUNLOCK(sc);
2593 }
2594
2595 static void
2596 rt2661_m_ioctl(void* arg, queue_t *wq, mblk_t *mp)
2597 {
2598 struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2599 struct ieee80211com *ic = &sc->sc_ic;
2600 int err;
2601
2602 err = ieee80211_ioctl(ic, wq, mp);
2603 RT2661_GLOCK(sc);
2604 if (err == ENETRESET) {
2605 if (ic->ic_des_esslen) {
2606 if (RT2661_IS_RUNNING(sc)) {
2607 RT2661_GUNLOCK(sc);
2608 (void) rt2661_init(sc);
2609 (void) ieee80211_new_state(ic,
2610 IEEE80211_S_SCAN, -1);
2611 RT2661_GLOCK(sc);
2612 }
2613 }
2614 }
2615 RT2661_GUNLOCK(sc);
2616 }
2617
2618 /*
2619 * Call back function for get/set proporty
2620 */
2621 static int
2622 rt2661_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2623 uint_t wldp_length, void *wldp_buf)
2624 {
2625 struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2626 int err = 0;
2627
2628 err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num,
2629 wldp_length, wldp_buf);
2630
2631 return (err);
2632 }
2633
2634 static void
2635 rt2661_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2636 mac_prop_info_handle_t mph)
2637 {
2638 struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2639
2640 ieee80211_propinfo(&sc->sc_ic, pr_name, wldp_pr_num, mph);
2641 }
2642
2643 static int
2644 rt2661_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2645 uint_t wldp_length, const void *wldp_buf)
2646 {
2647 struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2648 ieee80211com_t *ic = &sc->sc_ic;
2649 int err;
2650
2651 err = ieee80211_setprop(ic, pr_name, wldp_pr_num, wldp_length,
2652 wldp_buf);
2653 RT2661_GLOCK(sc);
2654 if (err == ENETRESET) {
2655 if (ic->ic_des_esslen) {
2656 if (RT2661_IS_RUNNING(sc)) {
2657 RT2661_GUNLOCK(sc);
2658 (void) rt2661_init(sc);
2659 (void) ieee80211_new_state(ic,
2660 IEEE80211_S_SCAN, -1);
2661 RT2661_GLOCK(sc);
2662 }
2663 }
2664 err = 0;
2665 }
2666 RT2661_GUNLOCK(sc);
2667 return (err);
2668 }
2669
2670 static mblk_t *
2671 rt2661_m_tx(void *arg, mblk_t *mp)
2672 {
2673 struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2674 struct ieee80211com *ic = &sc->sc_ic;
2675 mblk_t *next;
2676
2677 if (RT2661_IS_SUSPEND(sc)) {
2678 freemsgchain(mp);
2679 return (NULL);
2680 }
2681
2682 /*
2683 * No data frames go out unless we're associated; this
2684 * should not happen as the 802.11 layer does not enable
2685 * the xmit queue until we enter the RUN state.
2686 */
2687 if (ic->ic_state != IEEE80211_S_RUN) {
2688 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_data(): "
2689 "discard, state %u\n", ic->ic_state);
2690 freemsgchain(mp);
2691 return (NULL);
2692 }
2693
2694 while (mp != NULL) {
2695 next = mp->b_next;
2696 mp->b_next = NULL;
2697 if (rt2661_send(ic, mp) !=
2698 DDI_SUCCESS) {
2699 mp->b_next = next;
2700 break;
2701 }
2702 mp = next;
2703 }
2704 return (mp);
2705 }
2706
2707 /*ARGSUSED*/
2708 static int
2709 rt2661_m_unicst(void *arg, const uint8_t *macaddr)
2710 {
2711 return (ENOTSUP);
2712 }
2713
2714 /*ARGSUSED*/
2715 static int
2716 rt2661_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
2717 {
2718 return (ENOTSUP);
2719 }
2720
2721 /*ARGSUSED*/
2722 static int
2723 rt2661_m_promisc(void *arg, boolean_t on)
2724 {
2725 struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2726
2727 if (on) {
2728 sc->sc_rcr |= RT2661_RCR_PROMISC;
2729 sc->sc_rcr |= RT2661_RCR_MULTI;
2730 } else {
2731 sc->sc_rcr &= ~RT2661_RCR_PROMISC;
2732 sc->sc_rcr &= ~RT2661_RCR_MULTI;
2733 }
2734
2735 rt2661_update_promisc(sc);
2736 return (0);
2737 }
2738
2739 static int
2740 rt2661_m_stat(void *arg, uint_t stat, uint64_t *val)
2741 {
2742 struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2743 struct ieee80211com *ic = &sc->sc_ic;
2744 struct ieee80211_node *ni = ic->ic_bss;
2745 struct ieee80211_rateset *rs = &ni->in_rates;
2746
2747 RT2661_GLOCK(sc);
2748 switch (stat) {
2749 case MAC_STAT_IFSPEED:
2750 *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
2751 (rs->ir_rates[ni->in_txrate] & IEEE80211_RATE_VAL)
2752 : ic->ic_fixed_rate) / 2 * 1000000;
2753 break;
2754 case MAC_STAT_NOXMTBUF:
2755 *val = sc->sc_tx_nobuf;
2756 break;
2757 case MAC_STAT_NORCVBUF:
2758 *val = sc->sc_rx_nobuf;
2759 break;
2760 case MAC_STAT_IERRORS:
2761 *val = sc->sc_rx_err;
2762 break;
2763 case MAC_STAT_RBYTES:
2764 *val = ic->ic_stats.is_rx_bytes;
2765 break;
2766 case MAC_STAT_IPACKETS:
2767 *val = ic->ic_stats.is_rx_frags;
2768 break;
2769 case MAC_STAT_OBYTES:
2770 *val = ic->ic_stats.is_tx_bytes;
2771 break;
2772 case MAC_STAT_OPACKETS:
2773 *val = ic->ic_stats.is_tx_frags;
2774 break;
2775 case MAC_STAT_OERRORS:
2776 case WIFI_STAT_TX_FAILED:
2777 *val = sc->sc_tx_err;
2778 break;
2779 case WIFI_STAT_TX_RETRANS:
2780 *val = sc->sc_tx_retries;
2781 break;
2782 case WIFI_STAT_FCS_ERRORS:
2783 case WIFI_STAT_WEP_ERRORS:
2784 case WIFI_STAT_TX_FRAGS:
2785 case WIFI_STAT_MCAST_TX:
2786 case WIFI_STAT_RTS_SUCCESS:
2787 case WIFI_STAT_RTS_FAILURE:
2788 case WIFI_STAT_ACK_FAILURE:
2789 case WIFI_STAT_RX_FRAGS:
2790 case WIFI_STAT_MCAST_RX:
2791 case WIFI_STAT_RX_DUPS:
2792 RT2661_GUNLOCK(sc);
2793 return (ieee80211_stat(ic, stat, val));
2794 default:
2795 RT2661_GUNLOCK(sc);
2796 return (ENOTSUP);
2797 }
2798 RT2661_GUNLOCK(sc);
2799
2800 return (0);
2801 }
2802
2803 static int
2804 rt2661_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
2805 {
2806 struct rt2661_softc *sc;
2807 struct ieee80211com *ic;
2808
2809 int i, ac, err, ntries, instance;
2810 int intr_type, intr_count, intr_actual;
2811 char strbuf[32];
2812 uint8_t cachelsz;
2813 uint16_t command, vendor_id, device_id;
2814 uint32_t val;
2815
2816 wifi_data_t wd = { 0 };
2817 mac_register_t *macp;
2818
2819 switch (cmd) {
2820 case DDI_ATTACH:
2821 break;
2822 case DDI_RESUME:
2823 sc = ddi_get_soft_state(rt2661_soft_state_p,
2824 ddi_get_instance(devinfo));
2825 ASSERT(sc != NULL);
2826 RT2661_GLOCK(sc);
2827 sc->sc_flags &= ~RT2661_F_SUSPEND;
2828 RT2661_GUNLOCK(sc);
2829 if (RT2661_IS_RUNNING(sc))
2830 (void) rt2661_init(sc);
2831 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2832 "resume now\n");
2833 return (DDI_SUCCESS);
2834 default:
2835 return (DDI_FAILURE);
2836 }
2837
2838 instance = ddi_get_instance(devinfo);
2839
2840 err = ddi_soft_state_zalloc(rt2661_soft_state_p, instance);
2841 if (err != DDI_SUCCESS) {
2842 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2843 "unable to alloc soft_state_p\n");
2844 return (err);
2845 }
2846
2847 sc = ddi_get_soft_state(rt2661_soft_state_p, instance);
2848 ic = (struct ieee80211com *)&sc->sc_ic;
2849 sc->sc_dev = devinfo;
2850
2851 /* PCI configuration */
2852 err = ddi_regs_map_setup(devinfo, 0, &sc->sc_cfg_base, 0, 0,
2853 &rt2661_csr_accattr, &sc->sc_cfg_handle);
2854 if (err != DDI_SUCCESS) {
2855 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2856 "ddi_regs_map_setup() failed");
2857 goto fail1;
2858 }
2859
2860 cachelsz = ddi_get8(sc->sc_cfg_handle,
2861 (uint8_t *)(sc->sc_cfg_base + PCI_CONF_CACHE_LINESZ));
2862 if (cachelsz == 0)
2863 cachelsz = 0x10;
2864 sc->sc_cachelsz = cachelsz << 2;
2865 sc->sc_dmabuf_size = roundup(IEEE80211_MAX_LEN, sc->sc_cachelsz);
2866
2867 vendor_id = ddi_get16(sc->sc_cfg_handle,
2868 (uint16_t *)((uintptr_t)(sc->sc_cfg_base) + PCI_CONF_VENID));
2869 device_id = ddi_get16(sc->sc_cfg_handle,
2870 (uint16_t *)((uintptr_t)(sc->sc_cfg_base) + PCI_CONF_DEVID));
2871 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2872 "vendor 0x%x, device id 0x%x, cache size %d\n",
2873 vendor_id, device_id, cachelsz);
2874
2875 /*
2876 * Enable response to memory space accesses,
2877 * and enabe bus master.
2878 */
2879 command = PCI_COMM_MAE | PCI_COMM_ME;
2880 ddi_put16(sc->sc_cfg_handle,
2881 (uint16_t *)((uintptr_t)(sc->sc_cfg_base) + PCI_CONF_COMM),
2882 command);
2883 ddi_put8(sc->sc_cfg_handle,
2884 (uint8_t *)(sc->sc_cfg_base + PCI_CONF_LATENCY_TIMER), 0xa8);
2885 ddi_put8(sc->sc_cfg_handle,
2886 (uint8_t *)(sc->sc_cfg_base + PCI_CONF_ILINE), 0x10);
2887
2888 /* pci i/o space */
2889 err = ddi_regs_map_setup(devinfo, 1,
2890 &sc->sc_io_base, 0, 0, &rt2661_csr_accattr, &sc->sc_io_handle);
2891 if (err != DDI_SUCCESS) {
2892 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2893 "ddi_regs_map_setup() failed");
2894 goto fail2;
2895 }
2896 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2897 "PCI configuration is done successfully\n");
2898
2899 err = ddi_intr_get_supported_types(devinfo, &intr_type);
2900 if ((err != DDI_SUCCESS) || (!(intr_type & DDI_INTR_TYPE_FIXED))) {
2901 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2902 "fixed type interrupt is not supported\n");
2903 goto fail3;
2904 }
2905
2906 err = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_FIXED, &intr_count);
2907 if ((err != DDI_SUCCESS) || (intr_count != 1)) {
2908 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2909 "no fixed interrupts\n");
2910 goto fail3;
2911 }
2912
2913 sc->sc_intr_htable = kmem_zalloc(sizeof (ddi_intr_handle_t), KM_SLEEP);
2914
2915 err = ddi_intr_alloc(devinfo, sc->sc_intr_htable,
2916 DDI_INTR_TYPE_FIXED, 0, intr_count, &intr_actual, 0);
2917 if ((err != DDI_SUCCESS) || (intr_actual != 1)) {
2918 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2919 "ddi_intr_alloc() failed 0x%x\n", err);
2920 goto faili4;
2921 }
2922
2923 err = ddi_intr_get_pri(sc->sc_intr_htable[0], &sc->sc_intr_pri);
2924 if (err != DDI_SUCCESS) {
2925 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2926 "ddi_intr_get_pri() failed 0x%x\n", err);
2927 goto faili5;
2928 }
2929
2930 sc->amrr.amrr_min_success_threshold = 1;
2931 sc->amrr.amrr_max_success_threshold = 15;
2932
2933 /* wait for NIC to initialize */
2934 for (ntries = 0; ntries < 1000; ntries++) {
2935 if ((val = RT2661_READ(sc, RT2661_MAC_CSR0)) != 0)
2936 break;
2937 DELAY(1000);
2938 }
2939 if (ntries == 1000) {
2940 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2941 "timeout waiting for NIC to initialize\n");
2942 goto faili5;
2943 }
2944
2945 /* retrieve RF rev. no and various other things from EEPROM */
2946 rt2661_read_eeprom(sc);
2947
2948 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2949 "MAC/BBP RT%X, RF %s\n"
2950 "MAC address is: %x:%x:%x:%x:%x:%x\n", val,
2951 rt2661_get_rf(sc->rf_rev),
2952 ic->ic_macaddr[0], ic->ic_macaddr[1], ic->ic_macaddr[2],
2953 ic->ic_macaddr[3], ic->ic_macaddr[4], ic->ic_macaddr[5]);
2954
2955 /*
2956 * Load 8051 microcode into NIC.
2957 */
2958 switch (device_id) {
2959 case 0x0301:
2960 ucode = rt2561s_ucode;
2961 usize = sizeof (rt2561s_ucode);
2962 break;
2963 case 0x0302:
2964 ucode = rt2561_ucode;
2965 usize = sizeof (rt2561_ucode);
2966 break;
2967 case 0x0401:
2968 ucode = rt2661_ucode;
2969 usize = sizeof (rt2661_ucode);
2970 break;
2971 }
2972
2973 err = rt2661_load_microcode(sc, ucode, usize);
2974 if (err != RT2661_SUCCESS) {
2975 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2976 "could not load 8051 microcode\n");
2977 goto faili5;
2978 }
2979
2980 sc->sc_flags = 0;
2981 sc->sc_flags |= RT2661_F_FWLOADED;
2982
2983 /*
2984 * Allocate Tx and Rx rings.
2985 */
2986 for (ac = 0; ac < 4; ac++) {
2987 err = rt2661_alloc_tx_ring(sc, &sc->txq[ac],
2988 RT2661_TX_RING_COUNT);
2989 if (err != RT2661_SUCCESS) {
2990 RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_attach(): "
2991 "could not allocate Tx ring %d\n", ac);
2992 goto fail4;
2993 }
2994 }
2995
2996 err = rt2661_alloc_tx_ring(sc, &sc->mgtq, RT2661_MGT_RING_COUNT);
2997 if (err != RT2661_SUCCESS) {
2998 RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_attach(): "
2999 "could not allocate Mgt ring\n");
3000 goto fail5;
3001 }
3002
3003 err = rt2661_alloc_rx_ring(sc, &sc->rxq, RT2661_RX_RING_COUNT);
3004 if (err != RT2661_SUCCESS) {
3005 RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_attach(): "
3006 "could not allocate Rx ring\n");
3007 goto fail6;
3008 }
3009
3010 mutex_init(&sc->sc_genlock, NULL, MUTEX_DRIVER, NULL);
3011 mutex_init(&sc->sc_txlock, NULL, MUTEX_DRIVER, NULL);
3012 mutex_init(&sc->sc_rxlock, NULL, MUTEX_DRIVER, NULL);
3013
3014 ic->ic_phytype = IEEE80211_T_OFDM;
3015 ic->ic_opmode = IEEE80211_M_STA;
3016 ic->ic_state = IEEE80211_S_INIT;
3017
3018 /* set device capabilities */
3019 ic->ic_caps =
3020 IEEE80211_C_TXPMGT |
3021 IEEE80211_C_SHPREAMBLE |
3022 IEEE80211_C_SHSLOT;
3023
3024 /* WPA/WPA2 support */
3025 ic->ic_caps |= IEEE80211_C_WPA;
3026
3027 /* set supported .11b and .11g rates */
3028 ic->ic_sup_rates[IEEE80211_MODE_11B] = rt2661_rateset_11b;
3029 ic->ic_sup_rates[IEEE80211_MODE_11G] = rt2661_rateset_11g;
3030
3031 /* set supported .11b and .11g channels (1 through 14) */
3032 for (i = 1; i <= 14; i++) {
3033 ic->ic_sup_channels[i].ich_freq =
3034 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
3035 ic->ic_sup_channels[i].ich_flags =
3036 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
3037 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
3038 }
3039
3040 ic->ic_maxrssi = 63;
3041 ic->ic_xmit = rt2661_mgmt_send;
3042
3043 ieee80211_attach(ic);
3044
3045 /* register WPA door */
3046 ieee80211_register_door(ic, ddi_driver_name(devinfo),
3047 ddi_get_instance(devinfo));
3048
3049 ic->ic_node_alloc = rt2661_node_alloc;
3050 ic->ic_node_free = rt2661_node_free;
3051 ic->ic_set_shortslot = rt2661_updateslot;
3052
3053 /* override state transition machine */
3054 sc->sc_newstate = ic->ic_newstate;
3055 ic->ic_newstate = rt2661_newstate;
3056 ieee80211_media_init(ic);
3057 ic->ic_def_txkey = 0;
3058
3059 err = ddi_intr_add_softint(devinfo, &sc->sc_softintr_hdl,
3060 DDI_INTR_SOFTPRI_MAX, rt2661_softintr, (caddr_t)sc);
3061 if (err != DDI_SUCCESS) {
3062 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
3063 "ddi_add_softintr() failed");
3064 goto fail7;
3065 }
3066
3067 err = ddi_intr_add_handler(sc->sc_intr_htable[0], rt2661_intr,
3068 (caddr_t)sc, NULL);
3069 if (err != DDI_SUCCESS) {
3070 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
3071 "ddi_intr_addr_handle() failed\n");
3072 goto fail8;
3073 }
3074
3075 err = ddi_intr_enable(sc->sc_intr_htable[0]);
3076 if (err != DDI_SUCCESS) {
3077 RWD_DEBUG(RT2661_DBG_MSG, "rwd; rt2661_attach(): "
3078 "ddi_intr_enable() failed\n");
3079 goto fail9;
3080 }
3081
3082 /*
3083 * Provide initial settings for the WiFi plugin; whenever this
3084 * information changes, we need to call mac_plugindata_update()
3085 */
3086 wd.wd_opmode = ic->ic_opmode;
3087 wd.wd_secalloc = WIFI_SEC_NONE;
3088 IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid);
3089
3090 if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
3091 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
3092 "MAC version mismatch\n");
3093 goto fail10;
3094 }
3095
3096 macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI;
3097 macp->m_driver = sc;
3098 macp->m_dip = devinfo;
3099 macp->m_src_addr = ic->ic_macaddr;
3100 macp->m_callbacks = &rt2661_m_callbacks;
3101 macp->m_min_sdu = 0;
3102 macp->m_max_sdu = IEEE80211_MTU;
3103 macp->m_pdata = &wd;
3104 macp->m_pdata_size = sizeof (wd);
3105
3106 err = mac_register(macp, &ic->ic_mach);
3107 mac_free(macp);
3108 if (err != 0) {
3109 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
3110 "mac_register err %x\n", err);
3111 goto fail10;
3112 }
3113
3114 /*
3115 * Create minor node of type DDI_NT_NET_WIFI
3116 */
3117 (void) snprintf(strbuf, sizeof (strbuf), "%s%d",
3118 "rwd", instance);
3119 err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR,
3120 instance + 1, DDI_NT_NET_WIFI, 0);
3121
3122 /*
3123 * Notify link is down now
3124 */
3125 mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
3126
3127 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
3128 "attach successfully\n");
3129 return (DDI_SUCCESS);
3130
3131 fail10:
3132 (void) ddi_intr_disable(sc->sc_intr_htable[0]);
3133 fail9:
3134 (void) ddi_intr_remove_handler(sc->sc_intr_htable[0]);
3135 fail8:
3136 (void) ddi_intr_remove_softint(sc->sc_softintr_hdl);
3137 sc->sc_softintr_hdl = NULL;
3138 fail7:
3139 mutex_destroy(&sc->sc_genlock);
3140 mutex_destroy(&sc->sc_txlock);
3141 mutex_destroy(&sc->sc_rxlock);
3142 fail6:
3143 rt2661_free_rx_ring(sc, &sc->rxq);
3144 fail5:
3145 rt2661_free_tx_ring(sc, &sc->mgtq);
3146 fail4:
3147 while (--ac >= 0)
3148 rt2661_free_tx_ring(sc, &sc->txq[ac]);
3149 faili5:
3150 (void) ddi_intr_free(sc->sc_intr_htable[0]);
3151 faili4:
3152 kmem_free(sc->sc_intr_htable, sizeof (ddi_intr_handle_t));
3153 fail3:
3154 ddi_regs_map_free(&sc->sc_io_handle);
3155 fail2:
3156 ddi_regs_map_free(&sc->sc_cfg_handle);
3157 fail1:
3158 return (DDI_FAILURE);
3159 }
3160
3161 static int
3162 rt2661_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
3163 {
3164
3165 struct rt2661_softc *sc;
3166
3167 sc = ddi_get_soft_state(rt2661_soft_state_p, ddi_get_instance(devinfo));
3168
3169 switch (cmd) {
3170 case DDI_DETACH:
3171 break;
3172 case DDI_SUSPEND:
3173 if (RT2661_IS_RUNNING(sc))
3174 rt2661_stop(sc);
3175 RT2661_GLOCK(sc);
3176 sc->sc_flags |= RT2661_F_SUSPEND;
3177 sc->sc_flags &= ~RT2661_F_FWLOADED;
3178 RT2661_GUNLOCK(sc);
3179 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_detach(): "
3180 "suspend now\n");
3181 return (DDI_SUCCESS);
3182 default:
3183 return (DDI_FAILURE);
3184 }
3185
3186 if (mac_disable(sc->sc_ic.ic_mach) != 0)
3187 return (DDI_FAILURE);
3188
3189 /*
3190 * Unregister from the MAC layer subsystem
3191 */
3192 (void) mac_unregister(sc->sc_ic.ic_mach);
3193
3194 (void) ddi_intr_remove_softint(sc->sc_softintr_hdl);
3195 sc->sc_softintr_hdl = NULL;
3196 (void) ddi_intr_disable(sc->sc_intr_htable[0]);
3197 (void) ddi_intr_remove_handler(sc->sc_intr_htable[0]);
3198 (void) ddi_intr_free(sc->sc_intr_htable[0]);
3199 kmem_free(sc->sc_intr_htable, sizeof (ddi_intr_handle_t));
3200
3201 /*
3202 * detach ieee80211 layer
3203 */
3204 ieee80211_detach(&sc->sc_ic);
3205
3206 mutex_destroy(&sc->sc_genlock);
3207 mutex_destroy(&sc->sc_txlock);
3208 mutex_destroy(&sc->sc_rxlock);
3209
3210 rt2661_free_tx_ring(sc, &sc->txq[0]);
3211 rt2661_free_tx_ring(sc, &sc->txq[1]);
3212 rt2661_free_tx_ring(sc, &sc->txq[2]);
3213 rt2661_free_tx_ring(sc, &sc->txq[3]);
3214 rt2661_free_tx_ring(sc, &sc->mgtq);
3215 rt2661_free_rx_ring(sc, &sc->rxq);
3216
3217 ddi_regs_map_free(&sc->sc_io_handle);
3218 ddi_regs_map_free(&sc->sc_cfg_handle);
3219
3220 ddi_remove_minor_node(devinfo, NULL);
3221 ddi_soft_state_free(rt2661_soft_state_p, ddi_get_instance(devinfo));
3222
3223 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_detach(): "
3224 "detach successfully\n");
3225 return (DDI_SUCCESS);
3226 }
3227
3228 static int
3229 rt2661_quiesce(dev_info_t *dip)
3230 {
3231 struct rt2661_softc *sc;
3232
3233 sc = ddi_get_soft_state(rt2661_soft_state_p, ddi_get_instance(dip));
3234 if (sc == NULL)
3235 return (DDI_FAILURE);
3236
3237 #ifdef DEBUG
3238 rt2661_dbg_flags = 0;
3239 #endif
3240
3241 /*
3242 * No more blocking is allowed while we are in quiesce(9E) entry point
3243 */
3244 sc->sc_flags |= RT2661_F_QUIESCE;
3245
3246 /*
3247 * Disable all interrupts
3248 */
3249 rt2661_stop(sc);
3250 return (DDI_SUCCESS);
3251 }
3252
3253 int
3254 _info(struct modinfo *modinfop)
3255 {
3256 return (mod_info(&modlinkage, modinfop));
3257 }
3258
3259 int
3260 _init(void)
3261 {
3262 int status;
3263
3264 status = ddi_soft_state_init(&rt2661_soft_state_p,
3265 sizeof (struct rt2661_softc), 1);
3266 if (status != 0)
3267 return (status);
3268
3269 mac_init_ops(&rwd_dev_ops, "rwd");
3270 status = mod_install(&modlinkage);
3271 if (status != 0) {
3272 mac_fini_ops(&rwd_dev_ops);
3273 ddi_soft_state_fini(&rt2661_soft_state_p);
3274 }
3275 return (status);
3276 }
3277
3278 int
3279 _fini(void)
3280 {
3281 int status;
3282
3283 status = mod_remove(&modlinkage);
3284 if (status == 0) {
3285 mac_fini_ops(&rwd_dev_ops);
3286 ddi_soft_state_fini(&rt2661_soft_state_p);
3287 }
3288 return (status);
3289 }