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