Create per-interface sysctl tree.
[dragonfly.git] / sys / dev / netif / bwi / bwimac.c
1 /*
2  * Copyright (c) 2007 The DragonFly Project.  All rights reserved.
3  * 
4  * This code is derived from software contributed to The DragonFly Project
5  * by Sepherosa Ziehau <sepherosa@gmail.com>
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  * 
34  * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.5 2007/09/16 11:53:36 sephe Exp $
35  */
36
37 #include <sys/param.h>
38 #include <sys/endian.h>
39 #include <sys/kernel.h>
40 #include <sys/bus.h>
41 #include <sys/firmware.h>
42 #include <sys/malloc.h>
43 #include <sys/proc.h>
44 #include <sys/rman.h>
45 #include <sys/serialize.h>
46 #include <sys/socket.h>
47 #include <sys/sockio.h>
48 #include <sys/sysctl.h>
49
50 #include <net/ethernet.h>
51 #include <net/if.h>
52 #include <net/bpf.h>
53 #include <net/if_arp.h>
54 #include <net/if_dl.h>
55 #include <net/if_media.h>
56 #include <net/ifq_var.h>
57
58 #include <netproto/802_11/ieee80211_radiotap.h>
59 #include <netproto/802_11/ieee80211_var.h>
60
61 #include <bus/pci/pcireg.h>
62 #include <bus/pci/pcivar.h>
63 #include <bus/pci/pcidevs.h>
64
65 #include "bitops.h"
66 #include "if_bwireg.h"
67 #include "if_bwivar.h"
68 #include "bwiphy.h"
69 #include "bwirf.h"
70 #include "bwimac.h"
71
72 struct bwi_retry_lim {
73         uint16_t        shretry;
74         uint16_t        shretry_fb;
75         uint16_t        lgretry;
76         uint16_t        lgretry_fb;
77 };
78
79 static int      bwi_mac_test(struct bwi_mac *);
80 static int      bwi_mac_get_property(struct bwi_mac *);
81
82 static void     bwi_mac_set_retry_lim(struct bwi_mac *,
83                         const struct bwi_retry_lim *);
84 static void     bwi_mac_set_ackrates(struct bwi_mac *,
85                         const struct ieee80211_rateset *);
86
87 static int      bwi_mac_gpio_init(struct bwi_mac *);
88 static int      bwi_mac_gpio_fini(struct bwi_mac *);
89 static void     bwi_mac_opmode_init(struct bwi_mac *);
90 static void     bwi_mac_hostflags_init(struct bwi_mac *);
91 static void     bwi_mac_bss_param_init(struct bwi_mac *);
92
93 static int      bwi_mac_fw_alloc(struct bwi_mac *);
94 static void     bwi_mac_fw_free(struct bwi_mac *);
95 static int      bwi_mac_fw_load(struct bwi_mac *);
96 static int      bwi_mac_fw_init(struct bwi_mac *);
97 static int      bwi_mac_fw_load_iv(struct bwi_mac *, const struct fw_image *);
98
99 static void     bwi_mac_setup_tpctl(struct bwi_mac *);
100 static void     bwi_mac_adjust_tpctl(struct bwi_mac *, int, int);
101
102 static void     bwi_mac_lock(struct bwi_mac *);
103 static void     bwi_mac_unlock(struct bwi_mac *);
104
105 static const uint8_t bwi_sup_macrev[] = { 2, 4, 5, 6, 7, 9, 10 };
106
107 void
108 bwi_tmplt_write_4(struct bwi_mac *mac, uint32_t ofs, uint32_t val)
109 {
110         struct bwi_softc *sc = mac->mac_sc;
111
112         if (mac->mac_flags & BWI_MAC_F_BSWAP)
113                 val = bswap32(val);
114
115         CSR_WRITE_4(sc, BWI_MAC_TMPLT_CTRL, ofs);
116         CSR_WRITE_4(sc, BWI_MAC_TMPLT_DATA, val);
117 }
118
119 void
120 bwi_hostflags_write(struct bwi_mac *mac, uint64_t flags)
121 {
122         uint64_t val;
123
124         val = flags & 0xffff;
125         MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO, val);
126
127         val = (flags >> 16) & 0xffff;
128         MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI, val);
129
130         /* HI has unclear meaning, so leave it as it is */
131 }
132
133 uint64_t
134 bwi_hostflags_read(struct bwi_mac *mac)
135 {
136         uint64_t flags, val;
137
138         /* HI has unclear meaning, so don't touch it */
139         flags = 0;
140
141         val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI);
142         flags |= val << 16;
143
144         val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO);
145         flags |= val;
146
147         return flags;
148 }
149
150 uint16_t
151 bwi_memobj_read_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0)
152 {
153         struct bwi_softc *sc = mac->mac_sc;
154         uint32_t data_reg;
155         int ofs;
156
157         data_reg = BWI_MOBJ_DATA;
158         ofs = ofs0 / 4;
159
160         if (ofs0 % 4 != 0)
161                 data_reg = BWI_MOBJ_DATA_UNALIGN;
162
163         CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
164         return CSR_READ_2(sc, data_reg);
165 }
166
167 uint32_t
168 bwi_memobj_read_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0)
169 {
170         struct bwi_softc *sc = mac->mac_sc;
171         int ofs;
172
173         ofs = ofs0 / 4;
174         if (ofs0 % 4 != 0) {
175                 uint32_t ret;
176
177                 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
178                 ret = CSR_READ_2(sc, BWI_MOBJ_DATA_UNALIGN);
179                 ret <<= 16;
180
181                 CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
182                             BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1));
183                 ret |= CSR_READ_2(sc, BWI_MOBJ_DATA);
184
185                 return ret;
186         } else {
187                 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
188                 return CSR_READ_4(sc, BWI_MOBJ_DATA);
189         }
190 }
191
192 void
193 bwi_memobj_write_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0,
194                    uint16_t v)
195 {
196         struct bwi_softc *sc = mac->mac_sc;
197         uint32_t data_reg;
198         int ofs;
199
200         data_reg = BWI_MOBJ_DATA;
201         ofs = ofs0 / 4;
202
203         if (ofs0 % 4 != 0)
204                 data_reg = BWI_MOBJ_DATA_UNALIGN;
205
206         CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
207         CSR_WRITE_2(sc, data_reg, v);
208 }
209
210 void
211 bwi_memobj_write_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0,
212                    uint32_t v)
213 {
214         struct bwi_softc *sc = mac->mac_sc;
215         int ofs;
216
217         ofs = ofs0 / 4;
218         if (ofs0 % 4 != 0) {
219                 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
220                 CSR_WRITE_2(sc, BWI_MOBJ_DATA_UNALIGN, v >> 16);
221
222                 CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
223                             BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1));
224                 CSR_WRITE_2(sc, BWI_MOBJ_DATA, v & 0xffff);
225         } else {
226                 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
227                 CSR_WRITE_4(sc, BWI_MOBJ_DATA, v);
228         }
229 }
230
231 int
232 bwi_mac_lateattach(struct bwi_mac *mac)
233 {
234         int error;
235
236         if (mac->mac_rev >= 5)
237                 CSR_READ_4(mac->mac_sc, BWI_STATE_HI); /* dummy read */
238
239         bwi_mac_reset(mac, 1);
240
241         error = bwi_phy_attach(mac);
242         if (error)
243                 return error;
244
245         error = bwi_rf_attach(mac);
246         if (error)
247                 return error;
248
249         /* Link 11B/G PHY, unlink 11A PHY */
250         if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A)
251                 bwi_mac_reset(mac, 0);
252         else
253                 bwi_mac_reset(mac, 1);
254
255         error = bwi_mac_test(mac);
256         if (error)
257                 return error;
258
259         error = bwi_mac_get_property(mac);
260         if (error)
261                 return error;
262
263         error = bwi_rf_map_txpower(mac);
264         if (error)
265                 return error;
266
267         bwi_rf_off(mac);
268         CSR_WRITE_2(mac->mac_sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC);
269         bwi_regwin_disable(mac->mac_sc, &mac->mac_regwin, 0);
270
271         return 0;
272 }
273
274 int
275 bwi_mac_init(struct bwi_mac *mac)
276 {
277         struct bwi_softc *sc = mac->mac_sc;
278         int error, i;
279
280         /* Clear MAC/PHY/RF states */
281         bwi_mac_setup_tpctl(mac);
282         bwi_rf_clear_state(&mac->mac_rf);
283         bwi_phy_clear_state(&mac->mac_phy);
284
285         /* Enable MAC and linked it to PHY */
286         if (!bwi_regwin_is_enabled(sc, &mac->mac_regwin))
287                 bwi_mac_reset(mac, 1);
288
289         /* Initialize backplane */
290         error = bwi_bus_init(sc, mac);
291         if (error)
292                 return error;
293
294         /* XXX work around for hardware bugs? */
295         if (sc->sc_bus_regwin.rw_rev <= 5 &&
296             sc->sc_bus_regwin.rw_type != BWI_REGWIN_T_BUSPCIE) {
297                 CSR_SETBITS_4(sc, BWI_CONF_LO,
298                 __SHIFTIN(BWI_CONF_LO_SERVTO, BWI_CONF_LO_SERVTO_MASK) |
299                 __SHIFTIN(BWI_CONF_LO_REQTO, BWI_CONF_LO_REQTO_MASK));
300         }
301
302         /* Calibrate PHY */
303         error = bwi_phy_calibrate(mac);
304         if (error) {
305                 if_printf(&sc->sc_ic.ic_if, "PHY calibrate failed\n");
306                 return error;
307         }
308
309         /* Prepare to initialize firmware */
310         CSR_WRITE_4(sc, BWI_MAC_STATUS,
311                     BWI_MAC_STATUS_UCODE_JUMP0 |
312                     BWI_MAC_STATUS_IHREN);
313
314         /*
315          * Load and initialize firmwares
316          */
317         error = bwi_mac_fw_alloc(mac);
318         if (error)
319                 return error;
320
321         error = bwi_mac_fw_load(mac);
322         if (error)
323                 return error;
324
325         error = bwi_mac_gpio_init(mac);
326         if (error)
327                 return error;
328
329         error = bwi_mac_fw_init(mac);
330         if (error)
331                 return error;
332
333         /*
334          * Turn on RF
335          */
336         bwi_rf_on(mac);
337
338         /* TODO: LED, hardware rf enabled is only related to LED setting */
339
340         /*
341          * Initialize PHY
342          */
343         CSR_WRITE_4(sc, BWI_BBP_ATTEN, 0);
344         bwi_phy_init(mac);
345
346         /* TODO: interference mitigation */
347
348         /*
349          * Setup antenna mode
350          */
351         bwi_rf_set_ant_mode(mac, mac->mac_rf.rf_ant_mode);
352
353         /*
354          * Initialize operation mode (RX configuration)
355          */
356         bwi_mac_opmode_init(mac);
357
358         /* XXX what's these */
359         if (mac->mac_rev < 3) {
360                 CSR_WRITE_2(sc, 0x60e, 0);
361                 CSR_WRITE_2(sc, 0x610, 0x8000);
362                 CSR_WRITE_2(sc, 0x604, 0);
363                 CSR_WRITE_2(sc, 0x606, 0x200);
364         } else {
365                 CSR_WRITE_4(sc, 0x188, 0x80000000);
366                 CSR_WRITE_4(sc, 0x18c, 0x2000000);
367         }
368
369         /*
370          * Initialize TX/RX interrupts' mask
371          */
372         CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_TIMER1);
373         for (i = 0; i < BWI_TXRX_NRING; ++i) {
374                 uint32_t intrs;
375
376                 if (BWI_TXRX_IS_RX(i))
377                         intrs = BWI_TXRX_RX_INTRS;
378                 else
379                         intrs = BWI_TXRX_TX_INTRS;
380                 CSR_WRITE_4(sc, BWI_TXRX_INTR_MASK(i), intrs);
381         }
382
383         /* XXX what's this */
384         CSR_SETBITS_4(sc, BWI_STATE_LO, 0x100000);
385
386         /* Setup MAC power up delay */
387         CSR_WRITE_2(sc, BWI_MAC_POWERUP_DELAY, sc->sc_pwron_delay);
388
389         /* Set MAC regwin revision */
390         MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_MACREV, mac->mac_rev);
391
392         /*
393          * Initialize host flags
394          */
395         bwi_mac_hostflags_init(mac);
396
397         /*
398          * Initialize BSS parameters
399          */
400         bwi_mac_bss_param_init(mac);
401
402         /*
403          * Initialize TX rings
404          */
405         for (i = 0; i < BWI_TX_NRING; ++i) {
406                 error = sc->sc_init_tx_ring(sc, i);
407                 if (error) {
408                         if_printf(&sc->sc_ic.ic_if,
409                                   "can't initialize %dth TX ring\n", i);
410                         return error;
411                 }
412         }
413
414         /*
415          * Initialize RX ring
416          */
417         error = sc->sc_init_rx_ring(sc);
418         if (error) {
419                 if_printf(&sc->sc_ic.ic_if, "can't initialize RX ring\n");
420                 return error;
421         }
422
423         /*
424          * Initialize TX stats if the current MAC uses that
425          */
426         if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) {
427                 error = sc->sc_init_txstats(sc);
428                 if (error) {
429                         if_printf(&sc->sc_ic.ic_if,
430                                   "can't initialize TX stats ring\n");
431                         return error;
432                 }
433         }
434
435         /* XXX what's these */
436         CSR_WRITE_2(sc, 0x612, 0x50);   /* Force Pre-TBTT to 80? */
437         MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x416, 0x50);
438         MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x414, 0x1f4);
439
440         mac->mac_flags |= BWI_MAC_F_INITED;
441         return 0;
442 }
443
444 void
445 bwi_mac_reset(struct bwi_mac *mac, int link_phy)
446 {
447         struct bwi_softc *sc = mac->mac_sc;
448         uint32_t flags, state_lo, status;
449
450         flags = BWI_STATE_LO_FLAG_PHYRST | BWI_STATE_LO_FLAG_PHYCLKEN;
451         if (link_phy)
452                 flags |= BWI_STATE_LO_FLAG_PHYLNK;
453         bwi_regwin_enable(sc, &mac->mac_regwin, flags);
454         DELAY(2000);
455
456         state_lo = CSR_READ_4(sc, BWI_STATE_LO);
457         state_lo |= BWI_STATE_LO_GATED_CLOCK;
458         state_lo &= ~__SHIFTIN(BWI_STATE_LO_FLAG_PHYRST,
459                                BWI_STATE_LO_FLAGS_MASK);
460         CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
461         /* Flush pending bus write */
462         CSR_READ_4(sc, BWI_STATE_LO);
463         DELAY(1000);
464
465         state_lo &= ~BWI_STATE_LO_GATED_CLOCK;
466         CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
467         /* Flush pending bus write */
468         CSR_READ_4(sc, BWI_STATE_LO);
469         DELAY(1000);
470
471         CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
472
473         status = CSR_READ_4(sc, BWI_MAC_STATUS);
474         status |= BWI_MAC_STATUS_IHREN;
475         if (link_phy)
476                 status |= BWI_MAC_STATUS_PHYLNK;
477         else
478                 status &= ~BWI_MAC_STATUS_PHYLNK;
479         CSR_WRITE_4(sc, BWI_MAC_STATUS, status);
480
481         if (link_phy) {
482                 DPRINTF(sc, "%s\n", "PHY is linked");
483                 mac->mac_phy.phy_flags |= BWI_PHY_F_LINKED;
484         } else {
485                 DPRINTF(sc, "%s\n", "PHY is unlinked");
486                 mac->mac_phy.phy_flags &= ~BWI_PHY_F_LINKED;
487         }
488 }
489
490 void
491 bwi_mac_set_tpctl_11bg(struct bwi_mac *mac, const struct bwi_tpctl *new_tpctl)
492 {
493         struct bwi_rf *rf = &mac->mac_rf;
494         struct bwi_tpctl *tpctl = &mac->mac_tpctl;
495
496         if (new_tpctl != NULL) {
497                 KKASSERT(new_tpctl->bbp_atten <= BWI_BBP_ATTEN_MAX);
498                 KKASSERT(new_tpctl->rf_atten <=
499                          (rf->rf_rev < 6 ? BWI_RF_ATTEN_MAX0
500                                          : BWI_RF_ATTEN_MAX1));
501                 KKASSERT(new_tpctl->tp_ctrl1 <= BWI_TPCTL1_MAX);
502
503                 tpctl->bbp_atten = new_tpctl->bbp_atten;
504                 tpctl->rf_atten = new_tpctl->rf_atten;
505                 tpctl->tp_ctrl1 = new_tpctl->tp_ctrl1;
506         }
507
508         /* Set BBP attenuation */
509         bwi_phy_set_bbp_atten(mac, tpctl->bbp_atten);
510
511         /* Set RF attenuation */
512         RF_WRITE(mac, BWI_RFR_ATTEN, tpctl->rf_atten);
513         MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_RF_ATTEN,
514                      tpctl->rf_atten);
515
516         /* Set TX power */
517         if (rf->rf_type == BWI_RF_T_BCM2050) {
518                 RF_FILT_SETBITS(mac, BWI_RFR_TXPWR, ~BWI_RFR_TXPWR1_MASK,
519                         __SHIFTIN(tpctl->tp_ctrl1, BWI_RFR_TXPWR1_MASK));
520         }
521
522         /* Adjust RF Local Oscillator */
523         if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G)
524                 bwi_rf_lo_adjust(mac, tpctl);
525 }
526
527 static int
528 bwi_mac_test(struct bwi_mac *mac)
529 {
530         struct bwi_softc *sc = mac->mac_sc;
531         uint32_t orig_val, val;
532
533 #define TEST_VAL1       0xaa5555aa
534 #define TEST_VAL2       0x55aaaa55
535
536         /* Save it for later restoring */
537         orig_val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
538
539         /* Test 1 */
540         MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL1);
541         val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
542         if (val != TEST_VAL1) {
543                 device_printf(sc->sc_dev, "TEST1 failed\n");
544                 return ENXIO;
545         }
546
547         /* Test 2 */
548         MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL2);
549         val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
550         if (val != TEST_VAL2) {
551                 device_printf(sc->sc_dev, "TEST2 failed\n");
552                 return ENXIO;
553         }
554
555         /* Restore to the original value */
556         MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, orig_val);
557
558         val = CSR_READ_4(sc, BWI_MAC_STATUS);
559         if ((val & ~BWI_MAC_STATUS_PHYLNK) != BWI_MAC_STATUS_IHREN) {
560                 device_printf(sc->sc_dev, "%s failed, MAC status 0x%08x\n",
561                               __func__, val);
562                 return ENXIO;
563         }
564
565         val = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
566         if (val != 0) {
567                 device_printf(sc->sc_dev, "%s failed, intr status %08x\n",
568                               __func__, val);
569                 return ENXIO;
570         }
571
572 #undef TEST_VAL2
573 #undef TEST_VAL1
574
575         return 0;
576 }
577
578 static void
579 bwi_mac_setup_tpctl(struct bwi_mac *mac)
580 {
581         struct bwi_softc *sc = mac->mac_sc;
582         struct bwi_rf *rf = &mac->mac_rf;
583         struct bwi_phy *phy = &mac->mac_phy;
584         struct bwi_tpctl *tpctl = &mac->mac_tpctl;
585
586         /* Calc BBP attenuation */
587         if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev < 6)
588                 tpctl->bbp_atten = 0;
589         else
590                 tpctl->bbp_atten = 2;
591
592         /* Calc TX power CTRL1?? */
593         tpctl->tp_ctrl1 = 0;
594         if (rf->rf_type == BWI_RF_T_BCM2050) {
595                 if (rf->rf_rev == 1)
596                         tpctl->tp_ctrl1 = 3;
597                 else if (rf->rf_rev < 6)
598                         tpctl->tp_ctrl1 = 2;
599                 else if (rf->rf_rev == 8)
600                         tpctl->tp_ctrl1 = 1;
601         }
602
603         /* Empty TX power CTRL2?? */
604         tpctl->tp_ctrl2 = 0xffff;
605
606         /*
607          * Calc RF attenuation
608          */
609         if (phy->phy_mode == IEEE80211_MODE_11A) {
610                 tpctl->rf_atten = 0x60;
611                 goto back;
612         }
613
614         if (BWI_IS_BRCM_BCM4309G(sc) && sc->sc_pci_revid < 0x51) {
615                 tpctl->rf_atten = sc->sc_pci_revid < 0x43 ? 2 : 3;
616                 goto back;
617         }
618
619         tpctl->rf_atten = 5;
620
621         if (rf->rf_type != BWI_RF_T_BCM2050) {
622                 if (rf->rf_type == BWI_RF_T_BCM2053 && rf->rf_rev == 1)
623                         tpctl->rf_atten = 6;
624                 goto back;
625         }
626
627         /*
628          * NB: If we reaches here and the card is BRCM_BCM4309G,
629          *     then the card's PCI revision must >= 0x51
630          */
631
632         /* BCM2050 RF */
633         switch (rf->rf_rev) {
634         case 1:
635                 if (phy->phy_mode == IEEE80211_MODE_11G) {
636                         if (BWI_IS_BRCM_BCM4309G(sc) || BWI_IS_BRCM_BU4306(sc))
637                                 tpctl->rf_atten = 3;
638                         else
639                                 tpctl->rf_atten = 1;
640                 } else {
641                         if (BWI_IS_BRCM_BCM4309G(sc))
642                                 tpctl->rf_atten = 7;
643                         else
644                                 tpctl->rf_atten = 6;
645                 }
646                 break;
647         case 2:
648                 if (phy->phy_mode == IEEE80211_MODE_11G) {
649                         /*
650                          * NOTE: Order of following conditions is critical
651                          */
652                         if (BWI_IS_BRCM_BCM4309G(sc))
653                                 tpctl->rf_atten = 3;
654                         else if (BWI_IS_BRCM_BU4306(sc))
655                                 tpctl->rf_atten = 5;
656                         else if (sc->sc_bbp_id == BWI_BBPID_BCM4320)
657                                 tpctl->rf_atten = 4;
658                         else
659                                 tpctl->rf_atten = 3;
660                 } else {
661                         tpctl->rf_atten = 6;
662                 }
663                 break;
664         case 4:
665         case 5:
666                 tpctl->rf_atten = 1;
667                 break;
668         case 8:
669                 tpctl->rf_atten = 0x1a;
670                 break;
671         }
672 back:
673         DPRINTF(sc, "bbp atten: %u, rf atten: %u, ctrl1: %u, ctrl2: %u\n",
674                 tpctl->bbp_atten, tpctl->rf_atten,
675                 tpctl->tp_ctrl1, tpctl->tp_ctrl2);
676 }
677
678 void
679 bwi_mac_dummy_xmit(struct bwi_mac *mac)
680 {
681 #define PACKET_LEN      5
682         static const uint32_t   packet_11a[PACKET_LEN] =
683         { 0x000201cc, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
684         static const uint32_t   packet_11bg[PACKET_LEN] =
685         { 0x000b846e, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
686
687         struct bwi_softc *sc = mac->mac_sc;
688         struct bwi_rf *rf = &mac->mac_rf;
689         const uint32_t *packet;
690         uint16_t val_50c;
691         int wait_max, i;
692
693         if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) {
694                 wait_max = 30;
695                 packet = packet_11a;
696                 val_50c = 1;
697         } else {
698                 wait_max = 250;
699                 packet = packet_11bg;
700                 val_50c = 0;
701         }
702
703         for (i = 0; i < PACKET_LEN; ++i)
704                 TMPLT_WRITE_4(mac, i * 4, packet[i]);
705
706         CSR_READ_4(sc, BWI_MAC_STATUS); /* dummy read */
707
708         CSR_WRITE_2(sc, 0x568, 0);
709         CSR_WRITE_2(sc, 0x7c0, 0);
710         CSR_WRITE_2(sc, 0x50c, val_50c);
711         CSR_WRITE_2(sc, 0x508, 0);
712         CSR_WRITE_2(sc, 0x50a, 0);
713         CSR_WRITE_2(sc, 0x54c, 0);
714         CSR_WRITE_2(sc, 0x56a, 0x14);
715         CSR_WRITE_2(sc, 0x568, 0x826);
716         CSR_WRITE_2(sc, 0x500, 0);
717         CSR_WRITE_2(sc, 0x502, 0x30);
718
719         if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5)
720                 RF_WRITE(mac, 0x51, 0x17);
721
722         for (i = 0; i < wait_max; ++i) {
723                 if (CSR_READ_2(sc, 0x50e) & 0x80)
724                         break;
725                 DELAY(10);
726         }
727         for (i = 0; i < 10; ++i) {
728                 if (CSR_READ_2(sc, 0x50e) & 0x400)
729                         break;
730                 DELAY(10);
731         }
732         for (i = 0; i < 10; ++i) {
733                 if ((CSR_READ_2(sc, 0x690) & 0x100) == 0)
734                         break;
735                 DELAY(10);
736         }
737
738         if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5)
739                 RF_WRITE(mac, 0x51, 0x37);
740 #undef PACKET_LEN
741 }
742
743 void
744 bwi_mac_init_tpctl_11bg(struct bwi_mac *mac)
745 {
746         struct bwi_softc *sc = mac->mac_sc;
747         struct bwi_phy *phy = &mac->mac_phy;
748         struct bwi_rf *rf = &mac->mac_rf;
749         struct bwi_tpctl tpctl_orig;
750         int restore_tpctl = 0;
751
752         KKASSERT(phy->phy_mode != IEEE80211_MODE_11A);
753
754         if (BWI_IS_BRCM_BU4306(sc))
755                 return;
756
757         PHY_WRITE(mac, 0x28, 0x8018);
758         CSR_CLRBITS_2(sc, BWI_BBP_ATTEN, 0x20);
759
760         if (phy->phy_mode == IEEE80211_MODE_11G) {
761                 if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0)
762                         return;
763                 PHY_WRITE(mac, 0x47a, 0xc111);
764         }
765         if (mac->mac_flags & BWI_MAC_F_TPCTL_INITED)
766                 return;
767
768         if (phy->phy_mode == IEEE80211_MODE_11B && phy->phy_rev >= 2 &&
769             rf->rf_type == BWI_RF_T_BCM2050) {
770                 RF_SETBITS(mac, 0x76, 0x84);
771         } else {
772                 struct bwi_tpctl tpctl;
773
774                 /* Backup original TX power control variables */
775                 bcopy(&mac->mac_tpctl, &tpctl_orig, sizeof(tpctl_orig));
776                 restore_tpctl = 1;
777
778                 bcopy(&mac->mac_tpctl, &tpctl, sizeof(tpctl));
779                 tpctl.bbp_atten = 11;
780                 tpctl.tp_ctrl1 = 0;
781 #ifdef notyet
782                 if (rf->rf_rev >= 6 && rf->rf_rev <= 8)
783                         tpctl.rf_atten = 31;
784                 else
785 #endif
786                         tpctl.rf_atten = 9;
787
788                 bwi_mac_set_tpctl_11bg(mac, &tpctl);
789         }
790
791         bwi_mac_dummy_xmit(mac);
792
793         mac->mac_flags |= BWI_MAC_F_TPCTL_INITED;
794         rf->rf_base_tssi = PHY_READ(mac, 0x29);
795         DPRINTF(sc, "base tssi %d\n", rf->rf_base_tssi);
796
797         if (abs(rf->rf_base_tssi - rf->rf_idle_tssi) >= 20) {
798                 if_printf(&sc->sc_ic.ic_if, "base tssi measure failed\n");
799                 mac->mac_flags |= BWI_MAC_F_TPCTL_ERROR;
800         }
801
802         if (restore_tpctl)
803                 bwi_mac_set_tpctl_11bg(mac, &tpctl_orig);
804         else
805                 RF_CLRBITS(mac, 0x76, 0x84);
806
807         bwi_rf_clear_tssi(mac);
808 }
809
810 void
811 bwi_mac_detach(struct bwi_mac *mac)
812 {
813         bwi_mac_fw_free(mac);
814 }
815
816 static __inline int
817 bwi_fwimage_is_valid(struct bwi_softc *sc, const struct fw_image *fw,
818                      uint8_t fw_type)
819 {
820         const struct bwi_fwhdr *hdr;
821         struct ifnet *ifp = &sc->sc_ic.ic_if;
822
823         if (fw->fw_imglen < sizeof(*hdr)) {
824                 if_printf(ifp, "invalid firmware (%s): invalid size %u\n",
825                           fw->fw_name, fw->fw_imglen);
826                 return 0;
827         }
828
829         hdr = (const struct bwi_fwhdr *)fw->fw_image;
830
831         if (fw_type != BWI_FW_T_IV) {
832                 /*
833                  * Don't verify IV's size, it has different meaning
834                  */
835                 if (be32toh(hdr->fw_size) != fw->fw_imglen - sizeof(*hdr)) {
836                         if_printf(ifp, "invalid firmware (%s): size mismatch, "
837                                   "fw %u, real %u\n", fw->fw_name,
838                                   be32toh(hdr->fw_size),
839                                   fw->fw_imglen - sizeof(*hdr));
840                         return 0;
841                 }
842         }
843
844         if (hdr->fw_type != fw_type) {
845                 if_printf(ifp, "invalid firmware (%s): type mismatch, "
846                           "fw \'%c\', target \'%c\'\n", fw->fw_name,
847                           hdr->fw_type, fw_type);
848                 return 0;
849         }
850
851         if (hdr->fw_gen != BWI_FW_GEN_1) {
852                 if_printf(ifp, "invalid firmware (%s): wrong generation, "
853                           "fw %d, target %d\n", fw->fw_name,
854                           hdr->fw_gen, BWI_FW_GEN_1);
855                 return 0;
856         }
857         return 1;
858 }
859
860 /*
861  * XXX Error cleanup
862  */
863 static int
864 bwi_mac_fw_alloc(struct bwi_mac *mac)
865 {
866         struct bwi_softc *sc = mac->mac_sc;
867         struct ifnet *ifp = &sc->sc_ic.ic_if;
868         char fwname[64];
869         int idx;
870
871         if (mac->mac_ucode == NULL) {
872                 ksnprintf(fwname, sizeof(fwname), BWI_FW_UCODE_PATH,
873                           sc->sc_fw_version,
874                           mac->mac_rev >= 5 ? 5 : mac->mac_rev);
875
876                 mac->mac_ucode = firmware_image_load(fwname);
877                 if (mac->mac_ucode == NULL) {
878                         if_printf(ifp, "request firmware %s failed\n", fwname);
879                         return ENOMEM;
880                 }
881
882                 if (!bwi_fwimage_is_valid(sc, mac->mac_ucode, BWI_FW_T_UCODE))
883                         return EINVAL;
884         }
885
886         if (mac->mac_pcm == NULL) {
887                 ksnprintf(fwname, sizeof(fwname), BWI_FW_PCM_PATH,
888                           sc->sc_fw_version,
889                           mac->mac_rev < 5 ? 4 : 5);
890
891                 mac->mac_pcm = firmware_image_load(fwname);
892                 if (mac->mac_pcm == NULL) {
893                         if_printf(ifp, "request firmware %s failed\n", fwname);
894                         return ENOMEM;
895                 }
896
897                 if (!bwi_fwimage_is_valid(sc, mac->mac_pcm, BWI_FW_T_PCM))
898                         return EINVAL;
899         }
900
901         if (mac->mac_iv == NULL) {
902                 /* TODO: 11A */
903                 if (mac->mac_rev == 2 || mac->mac_rev == 4) {
904                         idx = 2;
905                 } else if (mac->mac_rev >= 5 && mac->mac_rev <= 10) {
906                         idx = 5;
907                 } else {
908                         if_printf(ifp, "no suitable IV for MAC rev %d\n",
909                                   mac->mac_rev);
910                         return ENODEV;
911                 }
912
913                 ksnprintf(fwname, sizeof(fwname), BWI_FW_IV_PATH,
914                           sc->sc_fw_version, idx);
915
916                 mac->mac_iv = firmware_image_load(fwname);
917                 if (mac->mac_iv == NULL) {
918                         if_printf(ifp, "request firmware %s failed\n", fwname);
919                         return ENOMEM;
920                 }
921                 if (!bwi_fwimage_is_valid(sc, mac->mac_iv, BWI_FW_T_IV))
922                         return EINVAL;
923         }
924
925         if (mac->mac_iv_ext == NULL) {
926                 /* TODO: 11A */
927                 if (mac->mac_rev == 2 || mac->mac_rev == 4 ||
928                     mac->mac_rev >= 11) {
929                         /* No extended IV */
930                         goto back;
931                 } else if (mac->mac_rev >= 5 && mac->mac_rev <= 10) {
932                         idx = 5;
933                 } else {
934                         if_printf(ifp, "no suitible ExtIV for MAC rev %d\n",
935                                   mac->mac_rev);
936                         return ENODEV;
937                 }
938
939                 ksnprintf(fwname, sizeof(fwname), BWI_FW_IV_EXT_PATH,
940                           sc->sc_fw_version, idx);
941
942                 mac->mac_iv_ext = firmware_image_load(fwname);
943                 if (mac->mac_iv_ext == NULL) {
944                         if_printf(ifp, "request firmware %s failed\n", fwname);
945                         return ENOMEM;
946                 }
947                 if (!bwi_fwimage_is_valid(sc, mac->mac_iv_ext, BWI_FW_T_IV))
948                         return EINVAL;
949         }
950 back:
951         return 0;
952 }
953
954 static void
955 bwi_mac_fw_free(struct bwi_mac *mac)
956 {
957         if (mac->mac_ucode != NULL) {
958                 firmware_image_unload(mac->mac_ucode);
959                 mac->mac_ucode = NULL;
960         }
961
962         if (mac->mac_pcm != NULL) {
963                 firmware_image_unload(mac->mac_pcm);
964                 mac->mac_pcm = NULL;
965         }
966
967         if (mac->mac_iv != NULL) {
968                 firmware_image_unload(mac->mac_iv);
969                 mac->mac_iv = NULL;
970         }
971
972         if (mac->mac_iv_ext != NULL) {
973                 firmware_image_unload(mac->mac_iv_ext);
974                 mac->mac_iv_ext = NULL;
975         }
976 }
977
978 static int
979 bwi_mac_fw_load(struct bwi_mac *mac)
980 {
981         struct bwi_softc *sc = mac->mac_sc;
982         struct ifnet *ifp = &sc->sc_ic.ic_if;
983         const uint32_t *fw;
984         uint16_t fw_rev;
985         int fw_len, i;
986
987         /*
988          * Load ucode image
989          */
990         fw = (const uint32_t *)
991              ((const uint8_t *)mac->mac_ucode->fw_image + BWI_FWHDR_SZ);
992         fw_len = (mac->mac_ucode->fw_imglen - BWI_FWHDR_SZ) / sizeof(uint32_t);
993
994         CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
995                     BWI_MOBJ_CTRL_VAL(
996                     BWI_FW_UCODE_MOBJ | BWI_WR_MOBJ_AUTOINC, 0));
997         for (i = 0; i < fw_len; ++i) {
998                 CSR_WRITE_4(sc, BWI_MOBJ_DATA, be32toh(fw[i]));
999                 DELAY(10);
1000         }
1001
1002         /*
1003          * Load PCM image
1004          */
1005         fw = (const uint32_t *)
1006              ((const uint8_t *)mac->mac_pcm->fw_image + BWI_FWHDR_SZ);
1007         fw_len = (mac->mac_pcm->fw_imglen - BWI_FWHDR_SZ) / sizeof(uint32_t);
1008
1009         CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1010                     BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01ea));
1011         CSR_WRITE_4(sc, BWI_MOBJ_DATA, 0x4000);
1012
1013         CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1014                     BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01eb));
1015         for (i = 0; i < fw_len; ++i) {
1016                 CSR_WRITE_4(sc, BWI_MOBJ_DATA, be32toh(fw[i]));
1017                 DELAY(10);
1018         }
1019
1020         CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_ALL_INTRS);
1021         CSR_WRITE_4(sc, BWI_MAC_STATUS,
1022                     BWI_MAC_STATUS_UCODE_START |
1023                     BWI_MAC_STATUS_IHREN |
1024                     BWI_MAC_STATUS_INFRA);
1025
1026 #define NRETRY  200
1027
1028         for (i = 0; i < NRETRY; ++i) {
1029                 uint32_t intr_status;
1030
1031                 intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
1032                 if (intr_status == BWI_INTR_READY)
1033                         break;
1034                 DELAY(10);
1035         }
1036         if (i == NRETRY) {
1037                 if_printf(ifp, "firmware (ucode&pcm) loading timed out\n");
1038                 return ETIMEDOUT;
1039         }
1040
1041 #undef NRETRY
1042
1043         CSR_READ_4(sc, BWI_MAC_INTR_STATUS);    /* dummy read */
1044
1045         fw_rev = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWREV);
1046         if (fw_rev > BWI_FW_VERSION3_REVMAX) {
1047                 if_printf(ifp, "firmware version 4 is not supported yet\n");
1048                 return ENODEV;
1049         }
1050
1051         if_printf(ifp, "firmware rev 0x%04x, patch level 0x%04x\n", fw_rev,
1052                   MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV));
1053         return 0;
1054 }
1055
1056 static int
1057 bwi_mac_gpio_init(struct bwi_mac *mac)
1058 {
1059         struct bwi_softc *sc = mac->mac_sc;
1060         struct bwi_regwin *old, *gpio_rw;
1061         uint32_t filt, bits;
1062         int error;
1063
1064         CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_GPOSEL_MASK);
1065         /* TODO:LED */
1066
1067         CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0xf);
1068
1069         filt = 0x1f;
1070         bits = 0xf;
1071         if (sc->sc_bbp_id == BWI_BBPID_BCM4301) {
1072                 filt |= 0x60;
1073                 bits |= 0x60;
1074         }
1075         if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) {
1076                 CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0x200);
1077                 filt |= 0x200;
1078                 bits |= 0x200;
1079         }
1080
1081         gpio_rw = BWI_GPIO_REGWIN(sc);
1082         error = bwi_regwin_switch(sc, gpio_rw, &old);
1083         if (error)
1084                 return error;
1085
1086         CSR_FILT_SETBITS_4(sc, BWI_GPIO_CTRL, filt, bits);
1087
1088         return bwi_regwin_switch(sc, old, NULL);
1089 }
1090
1091 static int
1092 bwi_mac_gpio_fini(struct bwi_mac *mac)
1093 {
1094         struct bwi_softc *sc = mac->mac_sc;
1095         struct bwi_regwin *old, *gpio_rw;
1096         int error;
1097
1098         gpio_rw = BWI_GPIO_REGWIN(sc);
1099         error = bwi_regwin_switch(sc, gpio_rw, &old);
1100         if (error)
1101                 return error;
1102
1103         CSR_WRITE_4(sc, BWI_GPIO_CTRL, 0);
1104
1105         return bwi_regwin_switch(sc, old, NULL);
1106 }
1107
1108 static int
1109 bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct fw_image *fw)
1110 {
1111         struct bwi_softc *sc = mac->mac_sc;
1112         struct ifnet *ifp = &sc->sc_ic.ic_if;
1113         const struct bwi_fwhdr *hdr;
1114         const struct bwi_fw_iv *iv;
1115         int n, i, iv_img_size;
1116
1117         /* Get the number of IVs in the IV image */
1118         hdr = (const struct bwi_fwhdr *)fw->fw_image;
1119         n = be32toh(hdr->fw_iv_cnt);
1120         DPRINTF(sc, "IV count %d\n", n);
1121
1122         /* Calculate the IV image size, for later sanity check */
1123         iv_img_size = fw->fw_imglen - sizeof(*hdr);
1124
1125         /* Locate the first IV */
1126         iv = (const struct bwi_fw_iv *)
1127              ((const uint8_t *)fw->fw_image + sizeof(*hdr));
1128
1129         for (i = 0; i < n; ++i) {
1130                 uint16_t iv_ofs, ofs;
1131                 int sz = 0;
1132
1133                 if (iv_img_size < sizeof(iv->iv_ofs)) {
1134                         if_printf(ifp, "invalid IV image, ofs\n");
1135                         return EINVAL;
1136                 }
1137                 iv_img_size -= sizeof(iv->iv_ofs);
1138                 sz += sizeof(iv->iv_ofs);
1139
1140                 iv_ofs = be16toh(iv->iv_ofs);
1141
1142                 ofs = __SHIFTOUT(iv_ofs, BWI_FW_IV_OFS_MASK);
1143                 if (ofs >= 0x1000) {
1144                         if_printf(ifp, "invalid ofs (0x%04x) "
1145                                   "for %dth iv\n", ofs, i);
1146                         return EINVAL;
1147                 }
1148
1149                 if (iv_ofs & BWI_FW_IV_IS_32BIT) {
1150                         uint32_t val32;
1151
1152                         if (iv_img_size < sizeof(iv->iv_val.val32)) {
1153                                 if_printf(ifp, "invalid IV image, val32\n");
1154                                 return EINVAL;
1155                         }
1156                         iv_img_size -= sizeof(iv->iv_val.val32);
1157                         sz += sizeof(iv->iv_val.val32);
1158
1159                         val32 = be32toh(iv->iv_val.val32);
1160                         CSR_WRITE_4(sc, ofs, val32);
1161                 } else {
1162                         uint16_t val16;
1163
1164                         if (iv_img_size < sizeof(iv->iv_val.val16)) {
1165                                 if_printf(ifp, "invalid IV image, val16\n");
1166                                 return EINVAL;
1167                         }
1168                         iv_img_size -= sizeof(iv->iv_val.val16);
1169                         sz += sizeof(iv->iv_val.val16);
1170
1171                         val16 = be16toh(iv->iv_val.val16);
1172                         CSR_WRITE_2(sc, ofs, val16);
1173                 }
1174
1175                 iv = (const struct bwi_fw_iv *)((const uint8_t *)iv + sz);
1176         }
1177
1178         if (iv_img_size != 0) {
1179                 if_printf(ifp, "invalid IV image, size left %d\n", iv_img_size);
1180                 return EINVAL;
1181         }
1182         return 0;
1183 }
1184
1185 static int
1186 bwi_mac_fw_init(struct bwi_mac *mac)
1187 {
1188         struct ifnet *ifp = &mac->mac_sc->sc_ic.ic_if;
1189         int error;
1190
1191         error = bwi_mac_fw_load_iv(mac, mac->mac_iv);
1192         if (error) {
1193                 if_printf(ifp, "load IV failed\n");
1194                 return error;
1195         }
1196
1197         if (mac->mac_iv_ext != NULL) {
1198                 error = bwi_mac_fw_load_iv(mac, mac->mac_iv_ext);
1199                 if (error)
1200                         if_printf(ifp, "load ExtIV failed\n");
1201         }
1202         return error;
1203 }
1204
1205 static void
1206 bwi_mac_opmode_init(struct bwi_mac *mac)
1207 {
1208         struct bwi_softc *sc = mac->mac_sc;
1209         struct ieee80211com *ic = &sc->sc_ic;
1210         uint32_t mac_status;
1211         uint16_t pre_tbtt;
1212
1213         CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA);
1214         CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA);
1215         CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PASS_BCN);
1216
1217         /* Set probe resp timeout to infinite */
1218         MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 0);
1219
1220         /*
1221          * TODO: factor out following part
1222          */
1223
1224         mac_status = CSR_READ_4(sc, BWI_MAC_STATUS);
1225         mac_status &= ~(BWI_MAC_STATUS_OPMODE_HOSTAP |
1226                         BWI_MAC_STATUS_PASS_CTL |
1227                         BWI_MAC_STATUS_PASS_BADPLCP |
1228                         BWI_MAC_STATUS_PASS_BADFCS |
1229                         BWI_MAC_STATUS_PROMISC);
1230         mac_status |= BWI_MAC_STATUS_INFRA;
1231
1232         /* Always turn on PROMISC on old hardware */
1233         if (mac->mac_rev < 5)
1234                 mac_status |= BWI_MAC_STATUS_PROMISC;
1235
1236         switch (ic->ic_opmode) {
1237         case IEEE80211_M_IBSS:
1238                 mac_status &= ~BWI_MAC_STATUS_INFRA;
1239                 break;
1240         case IEEE80211_M_HOSTAP:
1241                 mac_status |= BWI_MAC_STATUS_OPMODE_HOSTAP;
1242                 break;
1243         case IEEE80211_M_MONITOR:
1244 #if 0
1245                 /* Do you want data from your microwave oven? */
1246                 mac_status |= BWI_MAC_STATUS_PASS_CTL |
1247                               BWI_MAC_STATUS_PASS_BADPLCP |
1248                               BWI_MAC_STATUS_PASS_BADFCS;
1249 #else
1250                 mac_status |= BWI_MAC_STATUS_PASS_CTL;
1251 #endif
1252                 /* Promisc? */
1253                 break;
1254         default:
1255                 break;
1256         }
1257
1258         if (ic->ic_if.if_flags & IFF_PROMISC)
1259                 mac_status |= BWI_MAC_STATUS_PROMISC;
1260
1261         CSR_WRITE_4(sc, BWI_MAC_STATUS, mac_status);
1262
1263         if (ic->ic_opmode != IEEE80211_M_IBSS &&
1264             ic->ic_opmode != IEEE80211_M_HOSTAP) {
1265                 if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_rev == 3)
1266                         pre_tbtt = 100;
1267                 else
1268                         pre_tbtt = 50;
1269         } else {
1270                 pre_tbtt = 2;
1271         }
1272         CSR_WRITE_2(sc, BWI_MAC_PRE_TBTT, pre_tbtt);
1273 }
1274
1275 static void
1276 bwi_mac_hostflags_init(struct bwi_mac *mac)
1277 {
1278         struct bwi_softc *sc = mac->mac_sc;
1279         struct bwi_phy *phy = &mac->mac_phy;
1280         struct bwi_rf *rf = &mac->mac_rf;
1281         uint64_t host_flags;
1282
1283         if (phy->phy_mode == IEEE80211_MODE_11A)
1284                 return;
1285
1286         host_flags = HFLAGS_READ(mac);
1287         host_flags |= BWI_HFLAG_SYM_WA;
1288
1289         if (phy->phy_mode == IEEE80211_MODE_11G) {
1290                 if (phy->phy_rev == 1)
1291                         host_flags |= BWI_HFLAG_GDC_WA;
1292                 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
1293                         host_flags |= BWI_HFLAG_OFDM_PA;
1294         } else if (phy->phy_mode == IEEE80211_MODE_11B) {
1295                 if (phy->phy_rev >= 2 && rf->rf_type == BWI_RF_T_BCM2050)
1296                         host_flags &= ~BWI_HFLAG_GDC_WA;
1297         } else {
1298                 panic("unknown PHY mode %u\n", phy->phy_mode);
1299         }
1300
1301         HFLAGS_WRITE(mac, host_flags);
1302 }
1303
1304 static void
1305 bwi_mac_bss_param_init(struct bwi_mac *mac)
1306 {
1307         struct bwi_softc *sc = mac->mac_sc;
1308         struct bwi_phy *phy = &mac->mac_phy;
1309         struct bwi_retry_lim lim;
1310         uint16_t cw_min;
1311
1312         /*
1313          * Set short/long retry limits
1314          */
1315         bzero(&lim, sizeof(lim));
1316         lim.shretry = BWI_SHRETRY;
1317         lim.shretry_fb = BWI_SHRETRY_FB;
1318         lim.lgretry = BWI_LGRETRY;
1319         lim.lgretry_fb = BWI_LGRETRY_FB;
1320         bwi_mac_set_retry_lim(mac, &lim);
1321
1322         /*
1323          * Implicitly prevent firmware from sending probe response
1324          * by setting its "probe response timeout" to 1us.
1325          */
1326         MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 1);
1327
1328         /*
1329          * XXX MAC level acknowledge and CW min/max should depend
1330          * on the char rateset of the IBSS/BSS to join.
1331          */
1332
1333         /*
1334          * Set MAC level acknowledge rates
1335          */
1336         bwi_mac_set_ackrates(mac, &sc->sc_ic.ic_sup_rates[phy->phy_mode]);
1337
1338         /*
1339          * Set CW min
1340          */
1341         if (phy->phy_mode == IEEE80211_MODE_11B)
1342                 cw_min = IEEE80211_CW_MIN_0;
1343         else
1344                 cw_min = IEEE80211_CW_MIN_1;
1345         MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMIN, cw_min);
1346
1347         /*
1348          * Set CW max
1349          */
1350         MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMAX,
1351                      IEEE80211_CW_MAX);
1352 }
1353
1354 static void
1355 bwi_mac_set_retry_lim(struct bwi_mac *mac, const struct bwi_retry_lim *lim)
1356 {
1357         /* Short/Long retry limit */
1358         MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_SHRETRY,
1359                      lim->shretry);
1360         MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_LGRETRY,
1361                      lim->lgretry);
1362
1363         /* Short/Long retry fallback limit */
1364         MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SHRETRY_FB,
1365                      lim->shretry_fb);
1366         MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_LGRETEY_FB,
1367                      lim->lgretry_fb);
1368 }
1369
1370 static void
1371 bwi_mac_set_ackrates(struct bwi_mac *mac, const struct ieee80211_rateset *rs)
1372 {
1373         int i;
1374
1375         /* XXX not standard conforming */
1376         for (i = 0; i < rs->rs_nrates; ++i) {
1377                 enum ieee80211_modtype modtype;
1378                 uint16_t ofs;
1379
1380                 modtype = ieee80211_rate2modtype(rs->rs_rates[i]);
1381                 switch (modtype) {
1382                 case IEEE80211_MODTYPE_DS:
1383                         ofs = 0x4c0;
1384                         break;
1385                 case IEEE80211_MODTYPE_OFDM:
1386                         ofs = 0x480;
1387                         break;
1388                 default:
1389                         panic("unsupported modtype %u\n", modtype);
1390                 }
1391                 ofs += (bwi_rate2plcp(rs->rs_rates[i]) & 0xf) * 2;
1392
1393                 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, ofs + 0x20,
1394                              MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs));
1395         }
1396 }
1397
1398 int
1399 bwi_mac_start(struct bwi_mac *mac)
1400 {
1401         struct bwi_softc *sc = mac->mac_sc;
1402
1403         CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE);
1404         CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_READY);
1405
1406         /* Flush pending bus writes */
1407         CSR_READ_4(sc, BWI_MAC_STATUS);
1408         CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
1409
1410         return bwi_mac_config_ps(mac);
1411 }
1412
1413 int
1414 bwi_mac_stop(struct bwi_mac *mac)
1415 {
1416         struct bwi_softc *sc = mac->mac_sc;
1417         int error, i;
1418
1419         error = bwi_mac_config_ps(mac);
1420         if (error)
1421                 return error;
1422
1423         CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE);
1424
1425         /* Flush pending bus write */
1426         CSR_READ_4(sc, BWI_MAC_STATUS);
1427
1428 #define NRETRY  10000
1429         for (i = 0; i < NRETRY; ++i) {
1430                 if (CSR_READ_4(sc, BWI_MAC_INTR_STATUS) & BWI_INTR_READY)
1431                         break;
1432                 DELAY(1);
1433         }
1434         if (i == NRETRY) {
1435                 if_printf(&sc->sc_ic.ic_if, "can't stop MAC\n");
1436                 return ETIMEDOUT;
1437         }
1438 #undef NRETRY
1439
1440         return 0;
1441 }
1442
1443 int
1444 bwi_mac_config_ps(struct bwi_mac *mac)
1445 {
1446         struct bwi_softc *sc = mac->mac_sc;
1447         uint32_t status;
1448
1449         status = CSR_READ_4(sc, BWI_MAC_STATUS);
1450
1451         status &= ~BWI_MAC_STATUS_HW_PS;
1452         status |= BWI_MAC_STATUS_WAKEUP;
1453         CSR_WRITE_4(sc, BWI_MAC_STATUS, status);
1454
1455         /* Flush pending bus write */
1456         CSR_READ_4(sc, BWI_MAC_STATUS);
1457
1458         if (mac->mac_rev >= 5) {
1459                 int i;
1460
1461 #define NRETRY  100
1462                 for (i = 0; i < NRETRY; ++i) {
1463                         if (MOBJ_READ_2(mac, BWI_COMM_MOBJ,
1464                             BWI_COMM_MOBJ_UCODE_STATE) != BWI_UCODE_STATE_PS)
1465                                 break;
1466                         DELAY(10);
1467                 }
1468                 if (i == NRETRY) {
1469                         if_printf(&sc->sc_ic.ic_if, "config PS failed\n");
1470                         return ETIMEDOUT;
1471                 }
1472 #undef NRETRY
1473         }
1474         return 0;
1475 }
1476
1477 void
1478 bwi_mac_reset_hwkeys(struct bwi_mac *mac)
1479 {
1480         /* TODO: firmware crypto */
1481         MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_KEYTABLE_OFS);
1482 }
1483
1484 void
1485 bwi_mac_shutdown(struct bwi_mac *mac)
1486 {
1487         struct bwi_softc *sc = mac->mac_sc;
1488         int i;
1489
1490         if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS)
1491                 sc->sc_free_txstats(sc);
1492
1493         sc->sc_free_rx_ring(sc);
1494
1495         for (i = 0; i < BWI_TX_NRING; ++i)
1496                 sc->sc_free_tx_ring(sc, i);
1497
1498         bwi_rf_off(mac);
1499
1500         /* TODO:LED */
1501
1502         bwi_mac_gpio_fini(mac);
1503
1504         bwi_rf_off(mac); /* XXX again */
1505         CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC);
1506         bwi_regwin_disable(sc, &mac->mac_regwin, 0);
1507
1508         mac->mac_flags &= ~BWI_MAC_F_INITED;
1509 }
1510
1511 static int
1512 bwi_mac_get_property(struct bwi_mac *mac)
1513 {
1514         struct bwi_softc *sc = mac->mac_sc;
1515         enum bwi_bus_space old_bus_space;
1516         uint32_t val;
1517
1518         /*
1519          * Byte swap
1520          */
1521         val = CSR_READ_4(sc, BWI_MAC_STATUS);
1522         if (val & BWI_MAC_STATUS_BSWAP) {
1523                 DPRINTF(sc, "%s\n", "need byte swap");
1524                 mac->mac_flags |= BWI_MAC_F_BSWAP;
1525         }
1526
1527         /*
1528          * DMA address space
1529          */
1530         old_bus_space = sc->sc_bus_space;
1531
1532         val = CSR_READ_4(sc, BWI_STATE_HI);
1533         if (__SHIFTOUT(val, BWI_STATE_HI_FLAGS_MASK) &
1534             BWI_STATE_HI_FLAG_64BIT) {
1535                 /* 64bit address */
1536                 sc->sc_bus_space = BWI_BUS_SPACE_64BIT;
1537                 DPRINTF(sc, "%s\n", "64bit bus space");
1538         } else {
1539                 uint32_t txrx_reg = BWI_TXRX_CTRL_BASE + BWI_TX32_CTRL;
1540
1541                 CSR_WRITE_4(sc, txrx_reg, BWI_TXRX32_CTRL_ADDRHI_MASK);
1542                 if (CSR_READ_4(sc, txrx_reg) & BWI_TXRX32_CTRL_ADDRHI_MASK) {
1543                         /* 32bit address */
1544                         sc->sc_bus_space = BWI_BUS_SPACE_32BIT;
1545                         DPRINTF(sc, "%s\n", "32bit bus space");
1546                 } else {
1547                         /* 30bit address */
1548                         sc->sc_bus_space = BWI_BUS_SPACE_30BIT;
1549                         DPRINTF(sc, "%s\n", "30bit bus space");
1550                 }
1551         }
1552
1553         if (old_bus_space != 0 && old_bus_space != sc->sc_bus_space) {
1554                 device_printf(sc->sc_dev, "MACs bus space mismatch!\n");
1555                 return ENXIO;
1556         }
1557         return 0;
1558 }
1559
1560 void
1561 bwi_mac_updateslot(struct bwi_mac *mac, int shslot)
1562 {
1563         uint16_t slot_time;
1564
1565         if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B)
1566                 return;
1567
1568         if (shslot)
1569                 slot_time = IEEE80211_DUR_SHSLOT;
1570         else
1571                 slot_time = IEEE80211_DUR_SLOT;
1572
1573         CSR_WRITE_2(mac->mac_sc, BWI_MAC_SLOTTIME,
1574                     slot_time + BWI_MAC_SLOTTIME_ADJUST);
1575         MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SLOTTIME, slot_time);
1576 }
1577
1578 int
1579 bwi_mac_attach(struct bwi_softc *sc, int id, uint8_t rev)
1580 {
1581         struct bwi_mac *mac;
1582         int i;
1583
1584         KKASSERT(sc->sc_nmac <= BWI_MAC_MAX && sc->sc_nmac >= 0);
1585
1586         if (sc->sc_nmac == BWI_MAC_MAX) {
1587                 device_printf(sc->sc_dev, "too many MACs\n");
1588                 return 0;
1589         }
1590
1591         /*
1592          * More than one MAC is only supported by BCM4309
1593          */
1594         if (sc->sc_nmac != 0 &&
1595             pci_get_device(sc->sc_dev) != PCI_PRODUCT_BROADCOM_BCM4309) {
1596                 DPRINTF(sc, "%s\n", "ignore second MAC");
1597                 return 0;
1598         }
1599
1600         mac = &sc->sc_mac[sc->sc_nmac];
1601
1602         /* XXX will this happen? */
1603         if (BWI_REGWIN_EXIST(&mac->mac_regwin)) {
1604                 device_printf(sc->sc_dev, "%dth MAC already attached\n",
1605                               sc->sc_nmac);
1606                 return 0;
1607         }
1608
1609         /*
1610          * Test whether the revision of this MAC is supported
1611          */
1612 #define N(arr)  (int)(sizeof(arr) / sizeof(arr[0]))
1613         for (i = 0; i < N(bwi_sup_macrev); ++i) {
1614                 if (bwi_sup_macrev[i] == rev)
1615                         break;
1616         }
1617         if (i == N(bwi_sup_macrev)) {
1618                 device_printf(sc->sc_dev, "MAC rev %u is "
1619                               "not supported\n", rev);
1620                 return ENXIO;
1621         }
1622 #undef N
1623
1624         BWI_CREATE_MAC(mac, sc, id, rev);
1625         sc->sc_nmac++;
1626
1627         if (mac->mac_rev < 5) {
1628                 mac->mac_flags |= BWI_MAC_F_HAS_TXSTATS;
1629                 DPRINTF(sc, "%s\n", "has TX stats");
1630         }
1631
1632         device_printf(sc->sc_dev, "MAC: rev %u\n", rev);
1633         return 0;
1634 }
1635
1636 static __inline void
1637 bwi_mac_balance_atten(int *bbp_atten0, int *rf_atten0)
1638 {
1639         int bbp_atten, rf_atten, rf_atten_lim = -1;
1640
1641         bbp_atten = *bbp_atten0;
1642         rf_atten = *rf_atten0;
1643
1644         /*
1645          * RF attenuation affects TX power BWI_RF_ATTEN_FACTOR times
1646          * as much as BBP attenuation, so we try our best to keep RF
1647          * attenuation within range.  BBP attenuation will be clamped
1648          * later if it is out of range during balancing.
1649          *
1650          * BWI_RF_ATTEN_MAX0 is used as RF attenuation upper limit.
1651          */
1652
1653         /*
1654          * Use BBP attenuation to balance RF attenuation
1655          */
1656         if (rf_atten < 0)
1657                 rf_atten_lim = 0;
1658         else if (rf_atten > BWI_RF_ATTEN_MAX0)
1659                 rf_atten_lim = BWI_RF_ATTEN_MAX0;
1660
1661         if (rf_atten_lim >= 0) {
1662                 bbp_atten += (BWI_RF_ATTEN_FACTOR * (rf_atten - rf_atten_lim));
1663                 rf_atten = rf_atten_lim;
1664         }
1665
1666         /*
1667          * If possible, use RF attenuation to balance BBP attenuation
1668          * NOTE: RF attenuation is still kept within range.
1669          */
1670         while (rf_atten < BWI_RF_ATTEN_MAX0 && bbp_atten > BWI_BBP_ATTEN_MAX) {
1671                 bbp_atten -= BWI_RF_ATTEN_FACTOR;
1672                 ++rf_atten;
1673         }
1674         while (rf_atten > 0 && bbp_atten < 0) {
1675                 bbp_atten += BWI_RF_ATTEN_FACTOR;
1676                 --rf_atten;
1677         }
1678
1679         /* RF attenuation MUST be within range */
1680         KKASSERT(rf_atten >= 0 && rf_atten <= BWI_RF_ATTEN_MAX0);
1681
1682         /*
1683          * Clamp BBP attenuation
1684          */
1685         if (bbp_atten < 0)
1686                 bbp_atten = 0;
1687         else if (bbp_atten > BWI_BBP_ATTEN_MAX)
1688                 bbp_atten = BWI_BBP_ATTEN_MAX;
1689
1690         *rf_atten0 = rf_atten;
1691         *bbp_atten0 = bbp_atten;
1692 }
1693
1694 static void
1695 bwi_mac_adjust_tpctl(struct bwi_mac *mac, int rf_atten_adj, int bbp_atten_adj)
1696 {
1697         struct bwi_softc *sc = mac->mac_sc;
1698         struct bwi_rf *rf = &mac->mac_rf;
1699         struct bwi_tpctl tpctl;
1700         int bbp_atten, rf_atten, tp_ctrl1;
1701
1702         bcopy(&mac->mac_tpctl, &tpctl, sizeof(tpctl));
1703
1704         /* NOTE: Use signed value to do calulation */
1705         bbp_atten = tpctl.bbp_atten;
1706         rf_atten = tpctl.rf_atten;
1707         tp_ctrl1 = tpctl.tp_ctrl1;
1708
1709         bbp_atten += bbp_atten_adj;
1710         rf_atten += rf_atten_adj;
1711
1712         bwi_mac_balance_atten(&bbp_atten, &rf_atten);
1713
1714         if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 2) {
1715                 if (rf_atten <= 1) {
1716                         if (tp_ctrl1 == 0) {
1717                                 tp_ctrl1 = 3;
1718                                 bbp_atten += 2;
1719                                 rf_atten += 2;
1720                         } else if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) {
1721                                 bbp_atten +=
1722                                 (BWI_RF_ATTEN_FACTOR * (rf_atten - 2));
1723                                 rf_atten = 2;
1724                         }
1725                 } else if (rf_atten > 4 && tp_ctrl1 != 0) {
1726                         tp_ctrl1 = 0;
1727                         if (bbp_atten < 3) {
1728                                 bbp_atten += 2;
1729                                 rf_atten -= 3;
1730                         } else {
1731                                 bbp_atten -= 2;
1732                                 rf_atten -= 2;
1733                         }
1734                 }
1735                 bwi_mac_balance_atten(&bbp_atten, &rf_atten);
1736         }
1737
1738         tpctl.bbp_atten = bbp_atten;
1739         tpctl.rf_atten = rf_atten;
1740         tpctl.tp_ctrl1 = tp_ctrl1;
1741
1742         bwi_mac_lock(mac);
1743         bwi_mac_set_tpctl_11bg(mac, &tpctl);
1744         bwi_mac_unlock(mac);
1745 }
1746
1747 /*
1748  * http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower
1749  */
1750 void
1751 bwi_mac_calibrate_txpower(struct bwi_mac *mac)
1752 {
1753         struct bwi_softc *sc = mac->mac_sc;
1754         struct bwi_rf *rf = &mac->mac_rf;
1755         int8_t tssi[4], tssi_avg, cur_txpwr;
1756         int error, i, ofdm_tssi;
1757         int txpwr_diff, rf_atten_adj, bbp_atten_adj;
1758
1759         if (mac->mac_flags & BWI_MAC_F_TPCTL_ERROR) {
1760                 DPRINTF(sc, "%s\n", "tpctl error happened, can't set txpower");
1761                 return;
1762         }
1763
1764         if (BWI_IS_BRCM_BU4306(sc)) {
1765                 DPRINTF(sc, "%s\n", "BU4306, can't set txpower");
1766                 return;
1767         }
1768
1769         /*
1770          * Save latest TSSI and reset the related memory objects
1771          */
1772         ofdm_tssi = 0;
1773         error = bwi_rf_get_latest_tssi(mac, tssi, BWI_COMM_MOBJ_TSSI_DS);
1774         if (error) {
1775                 DPRINTF(sc, "%s\n", "no DS tssi");
1776
1777                 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B)
1778                         return;
1779
1780                 error = bwi_rf_get_latest_tssi(mac, tssi,
1781                                 BWI_COMM_MOBJ_TSSI_OFDM);
1782                 if (error) {
1783                         DPRINTF(sc, "%s\n", "no OFDM tssi");
1784                         return;
1785                 }
1786
1787                 for (i = 0; i < 4; ++i) {
1788                         tssi[i] += 0x20;
1789                         tssi[i] &= 0x3f;
1790                 }
1791                 ofdm_tssi = 1;
1792         }
1793         bwi_rf_clear_tssi(mac);
1794
1795         DPRINTF(sc, "tssi0 %d, tssi1 %d, tssi2 %d, tssi3 %d\n",
1796                 tssi[0], tssi[1], tssi[2], tssi[3]);
1797
1798         /*
1799          * Calculate RF/BBP attenuation adjustment based on
1800          * the difference between desired TX power and sampled
1801          * TX power.
1802          */
1803         /* +8 == "each incremented by 1/2" */
1804         tssi_avg = (tssi[0] + tssi[1] + tssi[2] + tssi[3] + 8) / 4;
1805         if (ofdm_tssi && (HFLAGS_READ(mac) & BWI_HFLAG_PWR_BOOST_DS))
1806                 tssi_avg -= 13;
1807
1808         DPRINTF(sc, "tssi avg %d\n", tssi_avg);
1809
1810         error = bwi_rf_tssi2dbm(mac, tssi_avg, &cur_txpwr);
1811         if (error)
1812                 return;
1813         DPRINTF(sc, "current txpower %d\n", cur_txpwr);
1814
1815         txpwr_diff = rf->rf_txpower_max - cur_txpwr; /* XXX ni_txpower */
1816
1817         rf_atten_adj = -howmany(txpwr_diff, 8);
1818         bbp_atten_adj = -(txpwr_diff / 2) -
1819                         (BWI_RF_ATTEN_FACTOR * rf_atten_adj);
1820
1821         if (rf_atten_adj == 0 && bbp_atten_adj == 0) {
1822                 DPRINTF(sc, "%s\n", "no need to adjust RF/BBP attenuation");
1823                 /* TODO: LO */
1824                 return;
1825         }
1826
1827         DPRINTF(sc, "rf atten adjust %d, bbp atten adjust %d\n",
1828                 rf_atten_adj, bbp_atten_adj);
1829         bwi_mac_adjust_tpctl(mac, rf_atten_adj, bbp_atten_adj);
1830         /* TODO: LO */
1831 }
1832
1833 static void
1834 bwi_mac_lock(struct bwi_mac *mac)
1835 {
1836         struct bwi_softc *sc = mac->mac_sc;
1837         struct ieee80211com *ic = &sc->sc_ic;
1838
1839         KKASSERT((mac->mac_flags & BWI_MAC_F_LOCKED) == 0);
1840
1841         if (mac->mac_rev < 3)
1842                 bwi_mac_stop(mac);
1843         else if (ic->ic_opmode != IEEE80211_M_HOSTAP)
1844                 bwi_mac_config_ps(mac);
1845
1846         CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK);
1847
1848         /* Flush pending bus write */
1849         CSR_READ_4(sc, BWI_MAC_STATUS);
1850         DELAY(10);
1851
1852         mac->mac_flags |= BWI_MAC_F_LOCKED;
1853 }
1854
1855 static void
1856 bwi_mac_unlock(struct bwi_mac *mac)
1857 {
1858         struct bwi_softc *sc = mac->mac_sc;
1859         struct ieee80211com *ic = &sc->sc_ic;
1860
1861         KKASSERT(mac->mac_flags & BWI_MAC_F_LOCKED);
1862
1863         CSR_READ_2(sc, BWI_PHYINFO); /* dummy read */
1864
1865         CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK);
1866
1867         if (mac->mac_rev < 3)
1868                 bwi_mac_start(mac);
1869         else if (ic->ic_opmode != IEEE80211_M_HOSTAP)
1870                 bwi_mac_config_ps(mac);
1871
1872         mac->mac_flags &= ~BWI_MAC_F_LOCKED;
1873 }
1874
1875 void
1876 bwi_mac_set_promisc(struct bwi_mac *mac, int promisc)
1877 {
1878         struct bwi_softc *sc = mac->mac_sc;
1879
1880         if (mac->mac_rev < 5) /* Promisc is always on */
1881                 return;
1882
1883         if (promisc)
1884                 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC);
1885         else
1886                 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC);
1887 }