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/iwm/if_iwm_sf.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) 2014 genua mbh <info@genua.de>
    3  * Copyright (c) 2014 Fixup Software Ltd.
    4  *
    5  * Permission to use, copy, modify, and distribute this software for any
    6  * purpose with or without fee is hereby granted, provided that the above
    7  * copyright notice and this permission notice appear in all copies.
    8  *
    9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   16  */
   17 
   18 /*-
   19  * Based on BSD-licensed source modules in the Linux iwlwifi driver,
   20  * which were used as the reference documentation for this implementation.
   21  *
   22  * Driver version we are currently based off of is
   23  * Linux 4.7.3 (tag id d7f6728f57e3ecbb7ef34eb7d9f564d514775d75)
   24  *
   25  ******************************************************************************
   26  *
   27  * This file is provided under a dual BSD/GPLv2 license.  When using or
   28  * redistributing this file, you may do so under either license.
   29  *
   30  * GPL LICENSE SUMMARY
   31  *
   32  * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
   33  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   34  *
   35  * This program is free software; you can redistribute it and/or modify
   36  * it under the terms of version 2 of the GNU General Public License as
   37  * published by the Free Software Foundation.
   38  *
   39  * This program is distributed in the hope that it will be useful, but
   40  * WITHOUT ANY WARRANTY; without even the implied warranty of
   41  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   42  * General Public License for more details.
   43  *
   44  * You should have received a copy of the GNU General Public License
   45  * along with this program; if not, write to the Free Software
   46  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
   47  * USA
   48  *
   49  * The full GNU General Public License is included in this distribution
   50  * in the file called COPYING.
   51  *
   52  * Contact Information:
   53  *  Intel Linux Wireless <linuxwifi@intel.com>
   54  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
   55  *
   56  * BSD LICENSE
   57  *
   58  * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
   59  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   60  * All rights reserved.
   61  *
   62  * Redistribution and use in source and binary forms, with or without
   63  * modification, are permitted provided that the following conditions
   64  * are met:
   65  *
   66  *  * Redistributions of source code must retain the above copyright
   67  *    notice, this list of conditions and the following disclaimer.
   68  *  * Redistributions in binary form must reproduce the above copyright
   69  *    notice, this list of conditions and the following disclaimer in
   70  *    the documentation and/or other materials provided with the
   71  *    distribution.
   72  *  * Neither the name Intel Corporation nor the names of its
   73  *    contributors may be used to endorse or promote products derived
   74  *    from this software without specific prior written permission.
   75  *
   76  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   77  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   78  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   79  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   80  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   81  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   82  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   83  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   84  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   85  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   86  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   87  *
   88  *****************************************************************************/
   89 
   90 #include <sys/cdefs.h>
   91 __FBSDID("$FreeBSD$");
   92 
   93 #include "opt_wlan.h"
   94 #include "opt_iwm.h"
   95 
   96 #include <sys/param.h>
   97 #include <sys/bus.h>
   98 #include <sys/conf.h>
   99 #include <sys/endian.h>
  100 #include <sys/firmware.h>
  101 #include <sys/kernel.h>
  102 #include <sys/malloc.h>
  103 #include <sys/mbuf.h>
  104 #include <sys/mutex.h>
  105 #include <sys/module.h>
  106 #include <sys/proc.h>
  107 #include <sys/rman.h>
  108 #include <sys/socket.h>
  109 #include <sys/sockio.h>
  110 #include <sys/sysctl.h>
  111 #include <sys/linker.h>
  112 
  113 #include <machine/bus.h>
  114 #include <machine/endian.h>
  115 #include <machine/resource.h>
  116 
  117 #include <net/if.h>
  118 #include <net/if_var.h>
  119 #include <net/if_arp.h>
  120 #include <net/if_dl.h>
  121 #include <net/if_media.h>
  122 #include <net/if_types.h>
  123 #include <net/bpf.h>
  124 
  125 #include <netinet/in.h>
  126 #include <netinet/in_systm.h>
  127 #include <netinet/if_ether.h>
  128 #include <netinet/ip.h>
  129 
  130 #include <net80211/ieee80211_var.h>
  131 #include <net80211/ieee80211_regdomain.h>
  132 #include <net80211/ieee80211_ratectl.h>
  133 #include <net80211/ieee80211_radiotap.h>
  134 
  135 #include <dev/iwm/if_iwmreg.h>
  136 #include <dev/iwm/if_iwmvar.h>
  137 #include <dev/iwm/if_iwm_config.h>
  138 #include <dev/iwm/if_iwm_debug.h>
  139 #include <dev/iwm/if_iwm_util.h>
  140 #include <dev/iwm/if_iwm_sf.h>
  141 
  142 /*
  143  * Aging and idle timeouts for the different possible scenarios
  144  * in default configuration
  145  */
  146 static const uint32_t
  147 sf_full_timeout_def[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = {
  148         {
  149                 htole32(IWM_SF_SINGLE_UNICAST_AGING_TIMER_DEF),
  150                 htole32(IWM_SF_SINGLE_UNICAST_IDLE_TIMER_DEF)
  151         },
  152         {
  153                 htole32(IWM_SF_AGG_UNICAST_AGING_TIMER_DEF),
  154                 htole32(IWM_SF_AGG_UNICAST_IDLE_TIMER_DEF)
  155         },
  156         {
  157                 htole32(IWM_SF_MCAST_AGING_TIMER_DEF),
  158                 htole32(IWM_SF_MCAST_IDLE_TIMER_DEF)
  159         },
  160         {
  161                 htole32(IWM_SF_BA_AGING_TIMER_DEF),
  162                 htole32(IWM_SF_BA_IDLE_TIMER_DEF)
  163         },
  164         {
  165                 htole32(IWM_SF_TX_RE_AGING_TIMER_DEF),
  166                 htole32(IWM_SF_TX_RE_IDLE_TIMER_DEF)
  167         },
  168 };
  169 
  170 /*
  171  * Aging and idle timeouts for the different possible scenarios
  172  * in single BSS MAC configuration.
  173  */
  174 static const uint32_t
  175 sf_full_timeout[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = {
  176         {
  177                 htole32(IWM_SF_SINGLE_UNICAST_AGING_TIMER),
  178                 htole32(IWM_SF_SINGLE_UNICAST_IDLE_TIMER)
  179         },
  180         {
  181                 htole32(IWM_SF_AGG_UNICAST_AGING_TIMER),
  182                 htole32(IWM_SF_AGG_UNICAST_IDLE_TIMER)
  183         },
  184         {
  185                 htole32(IWM_SF_MCAST_AGING_TIMER),
  186                 htole32(IWM_SF_MCAST_IDLE_TIMER)
  187         },
  188         {
  189                 htole32(IWM_SF_BA_AGING_TIMER),
  190                 htole32(IWM_SF_BA_IDLE_TIMER)
  191         },
  192         {
  193                 htole32(IWM_SF_TX_RE_AGING_TIMER),
  194                 htole32(IWM_SF_TX_RE_IDLE_TIMER)
  195         },
  196 };
  197 
  198 static void
  199 iwm_fill_sf_command(struct iwm_softc *sc, struct iwm_sf_cfg_cmd *sf_cmd,
  200         struct ieee80211_node *ni)
  201 {
  202         int i, j, watermark;
  203 
  204         sf_cmd->watermark[IWM_SF_LONG_DELAY_ON] = htole32(IWM_SF_W_MARK_SCAN);
  205 
  206         /*
  207          * If we are in association flow - check antenna configuration
  208          * capabilities of the AP station, and choose the watermark accordingly.
  209          */
  210         if (ni) {
  211                 if (ni->ni_flags & IEEE80211_NODE_HT) {
  212                         watermark = IWM_SF_W_MARK_SISO;
  213                 } else {
  214                         watermark = IWM_SF_W_MARK_LEGACY;
  215                 }
  216         /* default watermark value for unassociated mode. */
  217         } else {
  218                 watermark = IWM_SF_W_MARK_MIMO2;
  219         }
  220         sf_cmd->watermark[IWM_SF_FULL_ON] = htole32(watermark);
  221 
  222         for (i = 0; i < IWM_SF_NUM_SCENARIO; i++) {
  223                 for (j = 0; j < IWM_SF_NUM_TIMEOUT_TYPES; j++) {
  224                         sf_cmd->long_delay_timeouts[i][j] =
  225                                         htole32(IWM_SF_LONG_DELAY_AGING_TIMER);
  226                 }
  227         }
  228 
  229         if (ni) {
  230                 _Static_assert(sizeof(sf_full_timeout) == sizeof(uint32_t) *
  231                     IWM_SF_NUM_SCENARIO * IWM_SF_NUM_TIMEOUT_TYPES,
  232                     "sf_full_timeout has wrong size");
  233 
  234                 memcpy(sf_cmd->full_on_timeouts, sf_full_timeout,
  235                        sizeof(sf_full_timeout));
  236         } else {
  237                 _Static_assert(sizeof(sf_full_timeout_def) == sizeof(uint32_t) *
  238                     IWM_SF_NUM_SCENARIO * IWM_SF_NUM_TIMEOUT_TYPES,
  239                     "sf_full_timeout_def has wrong size");
  240 
  241                 memcpy(sf_cmd->full_on_timeouts, sf_full_timeout_def,
  242                        sizeof(sf_full_timeout_def));
  243         }
  244 }
  245 
  246 static int
  247 iwm_sf_config(struct iwm_softc *sc, struct ieee80211_node *ni,
  248         enum iwm_sf_state new_state)
  249 {
  250         struct iwm_sf_cfg_cmd sf_cmd = {
  251                 .state = htole32(new_state),
  252         };
  253         int ret = 0;
  254 
  255 #ifdef notyet   /* only relevant for sdio variants */
  256         if (sc->cfg->disable_dummy_notification)
  257                 sf_cmd.state |= htole32(IWM_SF_CFG_DUMMY_NOTIF_OFF);
  258 #endif
  259 
  260         /*
  261          * If an associated AP sta changed its antenna configuration, the state
  262          * will remain FULL_ON but SF parameters need to be reconsidered.
  263          */
  264         if (new_state != IWM_SF_FULL_ON && sc->sf_state == new_state)
  265                 return 0;
  266 
  267         switch (new_state) {
  268         case IWM_SF_UNINIT:
  269                 iwm_fill_sf_command(sc, &sf_cmd, NULL);
  270                 break;
  271         case IWM_SF_FULL_ON:
  272                 iwm_fill_sf_command(sc, &sf_cmd, ni);
  273                 break;
  274         case IWM_SF_INIT_OFF:
  275                 iwm_fill_sf_command(sc, &sf_cmd, NULL);
  276                 break;
  277         default:
  278                 device_printf(sc->sc_dev,
  279                     "Invalid state: %d. not sending Smart Fifo cmd\n",
  280                     new_state);
  281                 return EINVAL;
  282         }
  283 
  284         ret = iwm_send_cmd_pdu(sc, IWM_REPLY_SF_CFG_CMD, IWM_CMD_ASYNC,
  285                                    sizeof(sf_cmd), &sf_cmd);
  286         if (!ret)
  287                 sc->sf_state = new_state;
  288 
  289         return ret;
  290 }
  291 
  292 /*
  293  * Update Smart fifo:
  294  * Count bound interfaces that are not to be removed, ignoring p2p devices,
  295  * and set new state accordingly.
  296  */
  297 int
  298 iwm_sf_update(struct iwm_softc *sc, struct ieee80211vap *changed_vif,
  299         boolean_t remove_vif)
  300 {
  301         enum iwm_sf_state new_state;
  302         struct ieee80211_node *ni = NULL;
  303         int num_active_macs = 0;
  304 
  305         /* If changed_vif exists and is not to be removed, add to the count */
  306         if (changed_vif && !remove_vif)
  307                 num_active_macs++;
  308 
  309         switch (num_active_macs) {
  310         case 0:
  311                 /* If there are no active macs - change state to SF_INIT_OFF */
  312                 new_state = IWM_SF_INIT_OFF;
  313                 break;
  314         case 1:
  315                 if (!changed_vif)
  316                         return EINVAL;
  317                 ni = changed_vif->iv_bss;
  318                 if (ni != NULL && IWM_NODE(ni)->in_assoc &&
  319                     changed_vif->iv_dtim_period) {
  320                         new_state = IWM_SF_FULL_ON;
  321                 } else {
  322                         new_state = IWM_SF_INIT_OFF;
  323                 }
  324                 break;
  325         default:
  326                 /* If there are multiple active macs - change to SF_UNINIT */
  327                 new_state = IWM_SF_UNINIT;
  328         }
  329         return iwm_sf_config(sc, ni, new_state);
  330 }

Cache object: 9eec7696296063dc83277acdff5181c0


[ 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.