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