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