f80adda31a4bb8d4dd5300af8475226f96db3bcc
[dragonfly.git] / sys / dev / netif / acx / acx111.c
1 /*
2  * Copyright (c) 2006 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/acx/acx111.c,v 1.16 2008/06/08 10:06:05 sephe Exp $
35  */
36
37 #include <sys/param.h>
38 #include <sys/bus.h>
39 #include <sys/endian.h>
40 #include <sys/rman.h>
41 #include <sys/socket.h>
42 #include <sys/sysctl.h>
43
44 #include <net/if.h>
45 #include <net/if_arp.h>
46 #include <net/if_media.h>
47
48 #include <netproto/802_11/ieee80211_var.h>
49 #include <netproto/802_11/ieee80211_radiotap.h>
50 #include <netproto/802_11/wlan_ratectl/amrr/ieee80211_amrr_param.h>
51 #include <netproto/802_11/wlan_ratectl/onoe/ieee80211_onoe_param.h>
52
53 #include <bus/pci/pcireg.h>
54
55 #define ACX_DEBUG
56
57 #include <dev/netif/acx/if_acxreg.h>
58 #include <dev/netif/acx/if_acxvar.h>
59 #include <dev/netif/acx/acxcmd.h>
60
61 #define ACX111_CONF_MEM         0x0003
62 #define ACX111_CONF_MEMINFO     0x0005
63 #define ACX111_CONF_RT0_NRETRY  0x0006
64
65 #define ACX111_INTR_ENABLE      (ACXRV_INTR_TX_FINI | ACXRV_INTR_RX_FINI)
66 /*
67  * XXX do we really care about fowlling interrupts?
68  *
69  * ACXRV_INTR_IV_ICV_FAILURE | ACXRV_INTR_INFO |
70  * ACXRV_INTR_SCAN_FINI | ACXRV_INTR_FCS_THRESHOLD
71  */
72
73 #define ACX111_INTR_DISABLE     (uint16_t)~(ACXRV_INTR_CMD_FINI)
74
75 #define ACX111_RATE_2           0x0001
76 #define ACX111_RATE_4           0x0002
77 #define ACX111_RATE_11          0x0004
78 #define ACX111_RATE_12          0x0008
79 #define ACX111_RATE_18          0x0010
80 #define ACX111_RATE_22          0x0020
81 #define ACX111_RATE_24          0x0040
82 #define ACX111_RATE_36          0x0080
83 #define ACX111_RATE_44          0x0100
84 #define ACX111_RATE_48          0x0200
85 #define ACX111_RATE_72          0x0400
86 #define ACX111_RATE_96          0x0800
87 #define ACX111_RATE_108         0x1000
88 #define ACX111_RATE(rate)       [rate] = ACX111_RATE_##rate
89
90 #define ACX111_RSSI_CORR        5
91 #define ACX111_TXPOWER          15
92 #define ACX111_GPIO_POWER_LED   0x0040
93 #define ACX111_EE_EADDR_OFS     0x21
94
95 #define ACX111_FW_TXDESC_SIZE   (sizeof(struct acx_fw_txdesc) + 4)
96
97 #if ACX111_TXPOWER <= 12
98 #define ACX111_TXPOWER_VAL      1
99 #else
100 #define ACX111_TXPOWER_VAL      2
101 #endif
102
103 #define ACX111_ONOE_RATEIDX_MAX         4
104 #define ACX111_AMRR_RATEIDX_MAX         4
105
106 /*
107  * NOTE:
108  * Following structs' fields are little endian
109  */
110
111 struct acx111_bss_join {
112         uint16_t        basic_rates;
113         uint8_t         dtim_intvl;
114 } __packed;
115
116 struct acx111_calib {
117         uint32_t        calib;          /* ACX111_CALIB_ */
118         uint32_t        interval;       /* TU */
119 } __packed;
120
121 #define ACX111_CALIB_AUTO               0x80000000
122 #define ACX111_CALIB_DC                 0x00000001
123 #define ACX111_CALIB_AFE_DC             0x00000002
124 #define ACX111_CALIB_TX_MISMATCH        0x00000004
125 #define ACX111_CALIB_TX_EQUAL           0x00000008
126
127 #define ACX111_FW_CALIB_INTVL           IEEE80211_MS_TO_TU(60000) /* 60sec */
128
129 struct acx111_conf_mem {
130         struct acx_conf confcom;
131
132         uint16_t        sta_max;        /* max num of sta, ACX111_STA_MAX */
133         uint16_t        memblk_size;    /* mem block size */
134         uint8_t         rx_memblk_perc; /* percent of RX mem block, unit: 5% */
135         uint8_t         fw_rxring_num;  /* num of RX ring */
136         uint8_t         fw_txring_num;  /* num of TX ring */
137         uint8_t         opt;            /* see ACX111_MEMOPT_ */
138         uint8_t         xfer_perc;      /* frag/xfer proportion, unit: 5% */
139         uint16_t        reserved0;
140         uint8_t         reserved1;
141
142         uint8_t         fw_rxdesc_num;  /* num of fw rx desc */
143         uint8_t         fw_rxring_reserved1;
144         uint8_t         fw_rxring_type; /* see ACX111_RXRING_TYPE_ */
145         uint8_t         fw_rxring_prio; /* see ACX111_RXRING_PRIO_ */
146
147         uint32_t        h_rxring_paddr; /* host rx desc start phyaddr */
148
149         uint8_t         fw_txdesc_num;  /* num of fw tx desc */
150         uint8_t         fw_txring_reserved1;
151         uint8_t         fw_txring_reserved2;
152         uint8_t         fw_txring_attr; /* see ACX111_TXRING_ATTR_ */
153 } __packed;
154
155 /*
156  * ACX111 does support limited multi-rate retry, following rules apply to
157  * at least firmware rev1.2.x.x:
158  * 1) Rate field in firmware descriptor is a bitmask, which indicates
159  *    set of rates to be used to send the packet.
160  * 2) "acx111_conf_rt0_nretry" configures the number of retries for
161  *    1st rate.
162  * 3) Except for the last rate and 1st rate, rest of the rates in the
163  *    rate set are tried only once.
164  * 4) Last rate will be tried until "short retry limit" + "long retry limit"
165  *    reaches.
166  *
167  * e.g.
168  * a) 54Mbit/s, 48Mbit/s and 1Mbit/s are in the rate set.
169  * b) Number of retries for the 1st rate (i.e. 54Mbit/s) is set to 3.
170  * c) Short retry limit is set to 7
171  *
172  * For the above configuration:
173  * A) 4 tries will be spent at 54Mbit/s.
174  * B) 1 try will be spent at 48Mbit/s, if A) fails.
175  * C) 3 tries will be spent at 1Mbit/s, if A) and B) fail.
176  */
177 struct acx111_conf_rt0_nretry {
178         struct acx_conf confcom;
179         uint8_t         rt0_nretry;     /* number of retry for 1st rate */
180 } __packed;
181
182 #define ACX111_STA_MAX                  32
183 #define ACX111_RX_MEMBLK_PERCENT        10      /* 50% */
184 #define ACX111_XFER_PERCENT             15      /* 75% */
185 #define ACX111_RXRING_TYPE_DEFAULT      7
186 #define ACX111_RXRING_PRIO_DEFAULT      0
187 #define ACX111_TXRING_ATTR_DEFAULT      0
188 #define ACX111_MEMOPT_DEFAULT           0
189
190 struct acx111_conf_meminfo {
191         struct acx_conf confcom;
192         uint32_t        tx_memblk_addr; /* start addr of tx mem blocks */
193         uint32_t        rx_memblk_addr; /* start addr of rx mem blocks */
194         uint32_t        fw_rxring_start; /* start phyaddr of fw rx ring */
195         uint32_t        reserved0;
196         uint32_t        fw_txring_start; /* start phyaddr of fw tx ring */
197         uint8_t         fw_txring_attr; /* XXX see ACX111_TXRING_ATTR_ */
198         uint16_t        reserved1;
199         uint8_t         reserved2;
200 } __packed;
201
202 struct acx111_conf_txpower {
203         struct acx_conf confcom;
204         uint8_t         txpower;
205 } __packed;
206
207 struct acx111_conf_option {
208         struct acx_conf confcom;
209         uint32_t        feature;
210         uint32_t        dataflow;       /* see ACX111_DF_ */
211 } __packed;
212
213 #define ACX111_DF_NO_RXDECRYPT  0x00000080
214 #define ACX111_DF_NO_TXENCRYPT  0x00000001
215
216 struct acx111_wepkey {
217         uint8_t         mac_addr[IEEE80211_ADDR_LEN];
218         uint16_t        action;         /* see ACX111_WEPKEY_ACT_ */
219         uint16_t        reserved;
220         uint8_t         key_len;
221         uint8_t         key_type;       /* see ACX111_WEPKEY_TYPE_ */
222         uint8_t         index;          /* XXX ?? */
223         uint8_t         key_idx;
224         uint8_t         counter[6];
225 #define ACX111_WEPKEY_LEN       32
226         uint8_t         key[ACX111_WEPKEY_LEN];
227 } __packed;
228
229 #define ACX111_WEPKEY_ACT_ADD           1
230 #define ACX111_WEPKEY_TYPE_DEFAULT      0
231
232 #define ACX111_CONF_FUNC(sg, name)      _ACX_CONF_FUNC(sg, name, 111)
233 #define ACX_CONF_mem                    ACX111_CONF_MEM
234 #define ACX_CONF_meminfo                ACX111_CONF_MEMINFO
235 #define ACX_CONF_rt0_nretry             ACX111_CONF_RT0_NRETRY
236 #define ACX_CONF_txpower                ACX_CONF_TXPOWER
237 #define ACX_CONF_option                 ACX_CONF_OPTION
238 ACX111_CONF_FUNC(set, mem);
239 ACX111_CONF_FUNC(get, meminfo);
240 ACX111_CONF_FUNC(set, txpower);
241 ACX111_CONF_FUNC(get, option);
242 ACX111_CONF_FUNC(set, option);
243 ACX111_CONF_FUNC(set, rt0_nretry);
244
245 static const uint16_t acx111_reg[ACXREG_MAX] = {
246         ACXREG(SOFT_RESET,              0x0000),
247
248         ACXREG(FWMEM_ADDR,              0x0014),
249         ACXREG(FWMEM_DATA,              0x0018),
250         ACXREG(FWMEM_CTRL,              0x001c),
251         ACXREG(FWMEM_START,             0x0020),
252
253         ACXREG(EVENT_MASK,              0x0034),
254
255         ACXREG(INTR_TRIG,               0x00b4),
256         ACXREG(INTR_MASK,               0x00d4),
257         ACXREG(INTR_STATUS,             0x00f0),
258         ACXREG(INTR_STATUS_CLR,         0x00e4),
259         ACXREG(INTR_ACK,                0x00e8),
260
261         ACXREG(HINTR_TRIG,              0x00ec),
262         ACXREG(RADIO_ENABLE,            0x01d0),
263
264         ACXREG(EEPROM_INIT,             0x0100),
265         ACXREG(EEPROM_CTRL,             0x0338),
266         ACXREG(EEPROM_ADDR,             0x033c),
267         ACXREG(EEPROM_DATA,             0x0340),
268         ACXREG(EEPROM_CONF,             0x0344),
269         ACXREG(EEPROM_INFO,             0x0390),
270
271         ACXREG(PHY_ADDR,                0x0350),
272         ACXREG(PHY_DATA,                0x0354),
273         ACXREG(PHY_CTRL,                0x0358),
274
275         ACXREG(GPIO_OUT_ENABLE,         0x0374),
276         ACXREG(GPIO_OUT,                0x037c),
277
278         ACXREG(CMD_REG_OFFSET,          0x0388),
279         ACXREG(INFO_REG_OFFSET,         0x038c),
280
281         ACXREG(RESET_SENSE,             0x0104),
282         ACXREG(ECPU_CTRL,               0x0108) 
283 };
284
285 static const uint16_t   acx111_rate_map[109] = {
286         ACX111_RATE(2),
287         ACX111_RATE(4),
288         ACX111_RATE(11),
289         ACX111_RATE(22),
290         ACX111_RATE(12),
291         ACX111_RATE(18),
292         ACX111_RATE(24),
293         ACX111_RATE(36),
294         ACX111_RATE(44),
295         ACX111_RATE(48),
296         ACX111_RATE(72),
297         ACX111_RATE(96),
298         ACX111_RATE(108)
299 };
300
301 static const int
302 acx111_onoe_tries[IEEE80211_RATEIDX_MAX] = { 4, 1, 1, 3, 0 };
303
304 static const int
305 acx111_amrr_tries[IEEE80211_RATEIDX_MAX] = { 4, 1, 1, 3, 0 };
306
307 static int      acx111_init(struct acx_softc *);
308 static int      acx111_init_memory(struct acx_softc *);
309 static void     acx111_init_fw_txring(struct acx_softc *, uint32_t);
310
311 static int      acx111_write_config(struct acx_softc *, struct acx_config *);
312
313 static void     acx111_set_bss_join_param(struct acx_softc *, void *, int);
314 static int      acx111_calibrate(struct acx_softc *);
315
316 static void     *acx111_ratectl_attach(struct ieee80211com *, u_int);
317
318 static uint8_t  _acx111_set_fw_txdesc_rate(struct acx_softc *,
319                                            struct acx_txbuf *,
320                                            struct ieee80211_node *, int, int);
321 static uint8_t  acx111_set_fw_txdesc_rate_onoe(struct acx_softc *,
322                                                struct acx_txbuf *,
323                                                struct ieee80211_node *, int);
324 static uint8_t  acx111_set_fw_txdesc_rate_amrr(struct acx_softc *,
325                                                struct acx_txbuf *,
326                                                struct ieee80211_node *, int);
327
328 static void     _acx111_tx_complete(struct acx_softc *, struct acx_txbuf *,
329                                     int, int, const int[]);
330 static void     acx111_tx_complete_onoe(struct acx_softc *, struct acx_txbuf *,
331                                         int, int);
332 static void     acx111_tx_complete_amrr(struct acx_softc *, struct acx_txbuf *,
333                                         int, int);
334
335 #define ACX111_CHK_RATE(ifp, rate, rate_idx)    \
336         acx111_check_rate(ifp, rate, rate_idx, __func__)
337
338 static __inline int
339 acx111_check_rate(struct ifnet *ifp, u_int rate, int rate_idx,
340                   const char *fname)
341 {
342 #define N(arr)  (sizeof(arr) / sizeof(arr[0]))
343         if (rate >= N(acx111_rate_map)) {
344                 if_printf(ifp, "%s rate out of range %u (idx %d)\n",
345                           fname, rate, rate_idx);
346                 return -1;
347         }
348 #undef N
349
350         if (acx111_rate_map[rate] == 0) {
351                 if_printf(ifp, "%s invalid rate %u (idx %d)\n",
352                           fname, rate, rate_idx);
353                 return -1;
354         }
355         return 0;
356 }
357
358 void
359 acx111_set_param(device_t dev)
360 {
361         struct acx_softc *sc = device_get_softc(dev);
362         struct ieee80211com *ic = &sc->sc_ic;
363         struct acx_firmware *fw = &sc->sc_firmware;
364
365         sc->chip_mem1_rid = PCIR_BAR(0);
366         sc->chip_mem2_rid = PCIR_BAR(1);
367         sc->chip_ioreg = acx111_reg;
368         sc->chip_intr_enable = ACX111_INTR_ENABLE;
369         sc->chip_intr_disable = ACX111_INTR_DISABLE;
370         sc->chip_gpio_pled = ACX111_GPIO_POWER_LED;
371         sc->chip_ee_eaddr_ofs = ACX111_EE_EADDR_OFS;
372         sc->chip_rssi_corr = ACX111_RSSI_CORR;
373         sc->chip_calibrate = acx111_calibrate;
374
375         sc->chip_phymode = IEEE80211_MODE_11G;
376         sc->chip_chan_flags = IEEE80211_CHAN_CCK |
377                               IEEE80211_CHAN_OFDM |
378                               IEEE80211_CHAN_DYN |
379                               IEEE80211_CHAN_2GHZ;
380
381         ic->ic_caps = IEEE80211_C_WPA | IEEE80211_C_SHSLOT;
382         ic->ic_phytype = IEEE80211_T_OFDM;
383         if (acx_enable_pbcc) {
384                 ic->ic_sup_rates[IEEE80211_MODE_11B] = acx_rates_11b_pbcc;
385                 ic->ic_sup_rates[IEEE80211_MODE_11G] = acx_rates_11g_pbcc;
386         } else {
387                 ic->ic_sup_rates[IEEE80211_MODE_11B] = acx_rates_11b;
388                 ic->ic_sup_rates[IEEE80211_MODE_11G] = acx_rates_11g;
389         }
390
391         IEEE80211_ONOE_PARAM_SETUP(&sc->sc_onoe_param);
392         IEEE80211_AMRR_PARAM_SETUP(&sc->sc_amrr_param);
393
394         ic->ic_ratectl.rc_st_ratectl_cap = IEEE80211_RATECTL_CAP_ONOE |
395                                            IEEE80211_RATECTL_CAP_AMRR;
396         ic->ic_ratectl.rc_st_ratectl = IEEE80211_RATECTL_AMRR;
397         ic->ic_ratectl.rc_st_attach = acx111_ratectl_attach;
398
399         sc->chip_init = acx111_init;
400         sc->chip_write_config = acx111_write_config;
401         sc->chip_set_bss_join_param = acx111_set_bss_join_param;
402
403         fw->combined_radio_fw = 1;
404         fw->fwdir = "111";
405 }
406
407 static int
408 acx111_init(struct acx_softc *sc)
409 {
410         /*
411          * NOTE:
412          * Order of initialization:
413          * 1) Templates
414          * 2) Hardware memory
415          * Above order is critical to get a correct memory map
416          */
417
418         if (acx_init_tmplt_ordered(sc) != 0) {
419                 if_printf(&sc->sc_ic.ic_if, "%s can't initialize templates\n",
420                           __func__);
421                 return ENXIO;
422         }
423
424         if (acx111_init_memory(sc) != 0) {
425                 if_printf(&sc->sc_ic.ic_if, "%s can't initialize hw memory\n",
426                           __func__);
427                 return ENXIO;
428         }
429         return 0;
430 }
431
432 static int
433 acx111_init_memory(struct acx_softc *sc)
434 {
435         struct acx111_conf_mem mem;
436         struct acx111_conf_meminfo mem_info;
437
438         /* Set memory configuration */
439         bzero(&mem, sizeof(mem));
440
441         mem.sta_max = htole16(ACX111_STA_MAX);
442         mem.memblk_size = htole16(ACX_MEMBLOCK_SIZE);
443         mem.rx_memblk_perc = ACX111_RX_MEMBLK_PERCENT;
444         mem.opt = ACX111_MEMOPT_DEFAULT;
445         mem.xfer_perc = ACX111_XFER_PERCENT;
446
447         mem.fw_rxring_num = 1;
448         mem.fw_rxring_type = ACX111_RXRING_TYPE_DEFAULT;
449         mem.fw_rxring_prio = ACX111_RXRING_PRIO_DEFAULT;
450         mem.fw_rxdesc_num = ACX_RX_DESC_CNT;
451         mem.h_rxring_paddr = htole32(sc->sc_ring_data.rx_ring_paddr);
452
453         mem.fw_txring_num = 1;
454         mem.fw_txring_attr = ACX111_TXRING_ATTR_DEFAULT;
455         mem.fw_txdesc_num = ACX_TX_DESC_CNT;
456
457         if (acx111_set_mem_conf(sc, &mem) != 0) {
458                 if_printf(&sc->sc_ic.ic_if, "can't set mem\n");
459                 return 1;
460         }
461
462         /* Get memory configuration */
463         if (acx111_get_meminfo_conf(sc, &mem_info) != 0) {
464                 if_printf(&sc->sc_ic.ic_if, "can't get meminfo\n");
465                 return 1;
466         }
467
468         /* Setup firmware TX descriptor ring */
469         acx111_init_fw_txring(sc, le32toh(mem_info.fw_txring_start));
470
471         /*
472          * There is no need to setup firmware RX descriptor ring,
473          * it is automaticly setup by hardware.
474          */
475
476         return 0;
477 }
478
479 static void
480 acx111_init_fw_txring(struct acx_softc *sc, uint32_t fw_txdesc_start)
481 {
482         struct acx_txbuf *tx_buf;
483         uint32_t desc_paddr;
484         int i;
485
486         tx_buf = sc->sc_buf_data.tx_buf;
487         desc_paddr = sc->sc_ring_data.tx_ring_paddr;
488
489         for (i = 0; i < ACX_TX_DESC_CNT; ++i) {
490                 tx_buf[i].tb_fwdesc_ofs = fw_txdesc_start +
491                                           (i * ACX111_FW_TXDESC_SIZE);
492
493                 /*
494                  * Except for the following fields, rest of the fields
495                  * are setup by hardware.
496                  */
497                 FW_TXDESC_SETFIELD_4(sc, &tx_buf[i], f_tx_host_desc,
498                                      desc_paddr);
499                 FW_TXDESC_SETFIELD_1(sc, &tx_buf[i], f_tx_ctrl,
500                                      DESC_CTRL_HOSTOWN);
501
502                 desc_paddr += (2 * sizeof(struct acx_host_desc));
503         }
504 }
505
506 static int
507 acx111_write_config(struct acx_softc *sc, struct acx_config *conf)
508 {
509         struct acx111_conf_txpower tx_power;
510         struct acx111_conf_option opt;
511         struct acx111_conf_rt0_nretry rt0_nretry;
512         uint32_t dataflow;
513
514         /* Set TX power */
515         tx_power.txpower = ACX111_TXPOWER_VAL;
516         if (acx111_set_txpower_conf(sc, &tx_power) != 0) {
517                 if_printf(&sc->sc_ic.ic_if, "%s can't set TX power\n",
518                           __func__);
519                 return ENXIO;
520         }
521
522         /*
523          * Turn off hardware WEP
524          */
525         if (acx111_get_option_conf(sc, &opt) != 0) {
526                 if_printf(&sc->sc_ic.ic_if, "%s can't get option\n", __func__);
527                 return ENXIO;
528         }
529
530         dataflow = le32toh(opt.dataflow) |
531                    ACX111_DF_NO_TXENCRYPT |
532                    ACX111_DF_NO_RXDECRYPT;
533         opt.dataflow = htole32(dataflow);
534
535         if (acx111_set_option_conf(sc, &opt) != 0) {
536                 if_printf(&sc->sc_ic.ic_if, "%s can't set option\n", __func__);
537                 return ENXIO;
538         }
539
540         /*
541          * Set number of retries for 0th rate
542          */
543         rt0_nretry.rt0_nretry = sc->chip_rate_fallback;
544         if (acx111_set_rt0_nretry_conf(sc, &rt0_nretry) != 0) {
545                 if_printf(&sc->sc_ic.ic_if, "%s can't set rate0 nretry\n",
546                           __func__);
547                 return ENXIO;
548         }
549         return 0;
550 }
551
552 static uint8_t
553 _acx111_set_fw_txdesc_rate(struct acx_softc *sc, struct acx_txbuf *tx_buf,
554                            struct ieee80211_node *ni, int data_len,
555                            int rateidx_max)
556 {
557         struct ifnet *ifp = &sc->sc_ic.ic_if;
558         uint16_t rate;
559         uint8_t ret = 0;
560
561         KKASSERT(rateidx_max <= IEEE80211_RATEIDX_MAX);
562
563         if (ni == NULL) {
564                 rate = ACX111_RATE_2;   /* 1Mbit/s */
565                 ret = 2;
566                 tx_buf->tb_rateidx_len = 1;
567                 tx_buf->tb_rateidx[0] = 0;
568         } else {
569                 struct ieee80211_rateset *rs = &ni->ni_rates;
570                 int *rateidx = tx_buf->tb_rateidx;
571                 int i, n;
572
573                 n = ieee80211_ratectl_findrate(ni, data_len, rateidx,
574                                                rateidx_max);
575
576                 rate = 0;
577                 for (i = 0; i < n; ++i) {
578                         u_int map_idx = IEEE80211_RS_RATE(rs, rateidx[i]);
579
580                         if (ACX111_CHK_RATE(ifp, map_idx, rateidx[i]) < 0)
581                                 continue;
582
583                         if (ret == 0)
584                                 ret = map_idx;
585
586                         rate |= acx111_rate_map[map_idx];
587                 }
588                 if (rate == 0) {
589                         if_printf(ifp, "WARNING no rate, set to 1Mbit/s\n");
590                         rate = ACX111_RATE_2;
591                         ret = 2;
592                         tx_buf->tb_rateidx_len = 1;
593                         tx_buf->tb_rateidx[0] = 0;
594                 } else {
595                         tx_buf->tb_rateidx_len = n;
596                 }
597         }
598         FW_TXDESC_SETFIELD_2(sc, tx_buf, u.r2.rate111, rate);
599
600         return ret;
601 }
602
603 static uint8_t
604 acx111_set_fw_txdesc_rate_onoe(struct acx_softc *sc, struct acx_txbuf *tx_buf,
605                                struct ieee80211_node *ni, int data_len)
606 {
607         return _acx111_set_fw_txdesc_rate(sc, tx_buf, ni, data_len,
608                                           ACX111_ONOE_RATEIDX_MAX);
609 }
610
611 static uint8_t
612 acx111_set_fw_txdesc_rate_amrr(struct acx_softc *sc, struct acx_txbuf *tx_buf,
613                                struct ieee80211_node *ni, int data_len)
614 {
615         return _acx111_set_fw_txdesc_rate(sc, tx_buf, ni, data_len,
616                                           ACX111_AMRR_RATEIDX_MAX);
617 }
618
619 static void
620 acx111_set_bss_join_param(struct acx_softc *sc, void *param, int dtim_intvl)
621 {
622         struct acx111_bss_join *bj = param;
623         const struct ieee80211_rateset *rs = &sc->sc_ic.ic_bss->ni_rates;
624         struct ifnet *ifp = &sc->sc_ic.ic_if;
625         uint16_t basic_rates = 0;
626         int i;
627
628         for (i = 0; i < rs->rs_nrates; ++i) {
629                 if (rs->rs_rates[i] & IEEE80211_RATE_BASIC) {
630                         u_int map_idx = IEEE80211_RS_RATE(rs, i);
631
632                         if (ACX111_CHK_RATE(ifp, map_idx, i) < 0)
633                                 continue;
634
635                         basic_rates |= acx111_rate_map[map_idx];
636                 }
637         }
638         DPRINTF((ifp, "basic rates: 0x%04x\n", basic_rates));
639
640         bj->basic_rates = htole16(basic_rates);
641         bj->dtim_intvl = dtim_intvl;
642 }
643
644 static void *
645 acx111_ratectl_attach(struct ieee80211com *ic, u_int rc)
646 {
647         struct ifnet *ifp = &ic->ic_if;
648         struct acx_softc *sc = ifp->if_softc;
649         const int *tries;
650         void *ret;
651         int i;
652
653         switch (rc) {
654         case IEEE80211_RATECTL_ONOE:
655                 tries = acx111_onoe_tries;
656                 sc->chip_set_fw_txdesc_rate = acx111_set_fw_txdesc_rate_onoe;
657                 sc->chip_tx_complete = acx111_tx_complete_onoe;
658                 ret = &sc->sc_onoe_param;
659                 break;
660
661         case IEEE80211_RATECTL_AMRR:
662                 tries = acx111_amrr_tries;
663                 sc->chip_set_fw_txdesc_rate = acx111_set_fw_txdesc_rate_amrr;
664                 sc->chip_tx_complete = acx111_tx_complete_amrr;
665                 ret = &sc->sc_amrr_param;
666                 break;
667
668         case IEEE80211_RATECTL_NONE:
669                 /* This could only happen during detaching */
670                 return NULL;
671
672         default:
673                 panic("unknown rate control algo %u\n", rc);
674                 break;
675         }
676
677         sc->chip_rate_fallback = tries[0] - 1;
678
679         sc->chip_short_retry_limit = 0;
680         for (i = 0; i < IEEE80211_RATEIDX_MAX; ++i)
681                 sc->chip_short_retry_limit += tries[i];
682         sc->chip_short_retry_limit--;
683
684         if ((ifp->if_flags & (IFF_RUNNING | IFF_UP)) ==
685             (IFF_RUNNING | IFF_UP)) {
686                 struct acx_conf_nretry_short sretry;
687                 struct acx111_conf_rt0_nretry rt0_nretry;
688
689                 /*
690                  * Set number of short retries
691                  */
692                 sretry.nretry = sc->chip_short_retry_limit;
693                 if (acx_set_nretry_short_conf(sc, &sretry) != 0) {
694                         if_printf(ifp, "%s can't set short retry limit\n",
695                                   __func__);
696                 }
697                 DPRINTF((ifp, "%s set sretry %d\n", __func__,
698                          sc->chip_short_retry_limit));
699
700                 /*
701                  * Set number of retries for 0th rate
702                  */
703                 rt0_nretry.rt0_nretry = sc->chip_rate_fallback;
704                 if (acx111_set_rt0_nretry_conf(sc, &rt0_nretry) != 0) {
705                         if_printf(ifp, "%s can't set rate0 nretry\n",
706                                   __func__);
707                 }
708                 DPRINTF((ifp, "%s set rate 0 nretry %d\n", __func__,
709                          sc->chip_rate_fallback));
710         }
711         return ret;
712 }
713
714 static void
715 _acx111_tx_complete(struct acx_softc *sc, struct acx_txbuf *tx_buf,
716                     int frame_len, int is_fail, const int tries_arr[])
717 {
718         struct ieee80211_ratectl_res rc_res[IEEE80211_RATEIDX_MAX];
719         int rts_retries, data_retries, n, tries, prev_tries;
720
721         KKASSERT(tx_buf->tb_rateidx_len <= IEEE80211_RATEIDX_MAX);
722
723         rts_retries = FW_TXDESC_GETFIELD_1(sc, tx_buf, f_tx_rts_nretry);
724         data_retries = FW_TXDESC_GETFIELD_1(sc, tx_buf, f_tx_data_nretry);
725
726 #if 0
727         DPRINTF((&sc->sc_ic.ic_if, "d%d r%d rateidx_len %d\n",
728                  data_retries, rts_retries, tx_buf->tb_rateidx_len));
729 #endif
730
731         prev_tries = tries = 0;
732         for (n = 0; n < tx_buf->tb_rateidx_len; ++n) {
733                 rc_res[n].rc_res_tries = tries_arr[n];
734                 rc_res[n].rc_res_rateidx = tx_buf->tb_rateidx[n];
735                 if (!is_fail) {
736                         if (data_retries + 1 <= tries)
737                                 break;
738                         prev_tries = tries;
739                         tries += tries_arr[n];
740                 }
741         }
742         KKASSERT(n != 0);
743
744         if (!is_fail && data_retries + 1 <= tries) {
745                 rc_res[n - 1].rc_res_tries = data_retries + 1 - prev_tries;
746 #if 0
747                 DPRINTF((&sc->sc_ic.ic_if, "n %d, last tries%d\n",
748                          n, rc_res[n - 1].rc_res_tries));
749 #endif
750         }
751         ieee80211_ratectl_tx_complete(tx_buf->tb_node, frame_len, rc_res, n,
752                                       data_retries, rts_retries, is_fail);
753 }
754
755 static void
756 acx111_tx_complete_onoe(struct acx_softc *sc, struct acx_txbuf *tx_buf,
757                         int frame_len, int is_fail)
758 {
759         _acx111_tx_complete(sc, tx_buf, frame_len, is_fail,
760                             acx111_onoe_tries);
761 }
762
763 static void
764 acx111_tx_complete_amrr(struct acx_softc *sc, struct acx_txbuf *tx_buf,
765                         int frame_len, int is_fail)
766 {
767         _acx111_tx_complete(sc, tx_buf, frame_len, is_fail,
768                             acx111_amrr_tries);
769 }
770
771 static int
772 acx111_calibrate(struct acx_softc *sc)
773 {
774         struct acx111_calib calib;
775
776         calib.calib = htole32(ACX111_CALIB_AUTO |
777                               ACX111_CALIB_DC |
778                               ACX111_CALIB_AFE_DC |
779                               ACX111_CALIB_TX_MISMATCH |
780                               ACX111_CALIB_TX_EQUAL);
781         calib.interval = htole32(ACX111_FW_CALIB_INTVL);
782
783         return acx_exec_command(sc, ACXCMD_CALIBRATE, &calib, sizeof(calib),
784                                 NULL, 0);
785 }