The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/netif/acx/acx111.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.