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