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/ath/if_ath_keycache.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  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
    5  * All rights reserved.
    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  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer,
   12  *    without modification.
   13  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   14  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
   15  *    redistribution must be conditioned upon including a substantially
   16  *    similar Disclaimer requirement for further binary redistribution.
   17  *
   18  * NO WARRANTY
   19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   21  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
   22  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   23  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
   24  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   27  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   29  * THE POSSIBILITY OF SUCH DAMAGES.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD$");
   34 
   35 /*
   36  * Driver for the Atheros Wireless LAN controller.
   37  *
   38  * This software is derived from work of Atsushi Onoe; his contribution
   39  * is greatly appreciated.
   40  */
   41 
   42 #include "opt_inet.h"
   43 #include "opt_ath.h"
   44 #include "opt_wlan.h"
   45 
   46 #include <sys/param.h>
   47 #include <sys/systm.h>
   48 #include <sys/sysctl.h>
   49 #include <sys/mbuf.h>
   50 #include <sys/malloc.h>
   51 #include <sys/lock.h>
   52 #include <sys/mutex.h>
   53 #include <sys/kernel.h>
   54 #include <sys/socket.h>
   55 #include <sys/sockio.h>
   56 #include <sys/errno.h>
   57 #include <sys/callout.h>
   58 #include <sys/bus.h>
   59 #include <sys/endian.h>
   60 #include <sys/kthread.h>
   61 #include <sys/taskqueue.h>
   62 #include <sys/priv.h>
   63 
   64 #include <machine/bus.h>
   65 
   66 #include <net/if.h>
   67 #include <net/if_var.h>
   68 #include <net/if_dl.h>
   69 #include <net/if_media.h>
   70 #include <net/if_types.h>
   71 #include <net/if_arp.h>
   72 #include <net/ethernet.h>
   73 #include <net/if_llc.h>
   74 
   75 #include <net80211/ieee80211_var.h>
   76 
   77 #include <net/bpf.h>
   78 
   79 #include <dev/ath/if_athvar.h>
   80 
   81 #include <dev/ath/if_ath_debug.h>
   82 #include <dev/ath/if_ath_keycache.h>
   83 #include <dev/ath/if_ath_misc.h>
   84 
   85 #ifdef ATH_DEBUG
   86 static void
   87 ath_keyprint(struct ath_softc *sc, const char *tag, u_int ix,
   88         const HAL_KEYVAL *hk, const u_int8_t mac[IEEE80211_ADDR_LEN])
   89 {
   90         static const char *ciphers[] = {
   91                 "WEP",
   92                 "AES-OCB",
   93                 "AES-CCM",
   94                 "CKIP",
   95                 "TKIP",
   96                 "CLR",
   97         };
   98         int i, n;
   99 
  100         printf("%s: [%02u] %-7s ", tag, ix, ciphers[hk->kv_type]);
  101         for (i = 0, n = hk->kv_len; i < n; i++)
  102                 printf("%02x", hk->kv_val[i]);
  103         printf(" mac %s", ether_sprintf(mac));
  104         if (hk->kv_type == HAL_CIPHER_TKIP) {
  105                 printf(" %s ", sc->sc_splitmic ? "mic" : "rxmic");
  106                 for (i = 0; i < sizeof(hk->kv_mic); i++)
  107                         printf("%02x", hk->kv_mic[i]);
  108                 if (!sc->sc_splitmic) {
  109                         printf(" txmic ");
  110                         for (i = 0; i < sizeof(hk->kv_txmic); i++)
  111                                 printf("%02x", hk->kv_txmic[i]);
  112                 }
  113         }
  114         printf("\n");
  115 }
  116 #endif
  117 
  118 /*
  119  * Set a TKIP key into the hardware.  This handles the
  120  * potential distribution of key state to multiple key
  121  * cache slots for TKIP.
  122  */
  123 static int
  124 ath_keyset_tkip(struct ath_softc *sc, const struct ieee80211_key *k,
  125         HAL_KEYVAL *hk, const u_int8_t mac[IEEE80211_ADDR_LEN])
  126 {
  127 #define IEEE80211_KEY_XR        (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV)
  128         static const u_int8_t zerobssid[IEEE80211_ADDR_LEN];
  129         struct ath_hal *ah = sc->sc_ah;
  130 
  131         KASSERT(k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP,
  132                 ("got a non-TKIP key, cipher %u", k->wk_cipher->ic_cipher));
  133         if ((k->wk_flags & IEEE80211_KEY_XR) == IEEE80211_KEY_XR) {
  134                 if (sc->sc_splitmic) {
  135                         /*
  136                          * TX key goes at first index, RX key at the rx index.
  137                          * The hal handles the MIC keys at index+64.
  138                          */
  139                         memcpy(hk->kv_mic, k->wk_txmic, sizeof(hk->kv_mic));
  140                         KEYPRINTF(sc, k->wk_keyix, hk, zerobssid);
  141                         if (!ath_hal_keyset(ah, k->wk_keyix, hk, zerobssid))
  142                                 return 0;
  143 
  144                         memcpy(hk->kv_mic, k->wk_rxmic, sizeof(hk->kv_mic));
  145                         KEYPRINTF(sc, k->wk_keyix+32, hk, mac);
  146                         /* XXX delete tx key on failure? */
  147                         return ath_hal_keyset(ah, k->wk_keyix+32, hk, mac);
  148                 } else {
  149                         /*
  150                          * Room for both TX+RX MIC keys in one key cache
  151                          * slot, just set key at the first index; the hal
  152                          * will handle the rest.
  153                          */
  154                         memcpy(hk->kv_mic, k->wk_rxmic, sizeof(hk->kv_mic));
  155                         memcpy(hk->kv_txmic, k->wk_txmic, sizeof(hk->kv_txmic));
  156                         KEYPRINTF(sc, k->wk_keyix, hk, mac);
  157                         return ath_hal_keyset(ah, k->wk_keyix, hk, mac);
  158                 }
  159         } else if (k->wk_flags & IEEE80211_KEY_XMIT) {
  160                 if (sc->sc_splitmic) {
  161                         /*
  162                          * NB: must pass MIC key in expected location when
  163                          * the keycache only holds one MIC key per entry.
  164                          */
  165                         memcpy(hk->kv_mic, k->wk_txmic, sizeof(hk->kv_txmic));
  166                 } else
  167                         memcpy(hk->kv_txmic, k->wk_txmic, sizeof(hk->kv_txmic));
  168                 KEYPRINTF(sc, k->wk_keyix, hk, mac);
  169                 return ath_hal_keyset(ah, k->wk_keyix, hk, mac);
  170         } else if (k->wk_flags & IEEE80211_KEY_RECV) {
  171                 memcpy(hk->kv_mic, k->wk_rxmic, sizeof(hk->kv_mic));
  172                 KEYPRINTF(sc, k->wk_keyix, hk, mac);
  173                 return ath_hal_keyset(ah, k->wk_keyix, hk, mac);
  174         }
  175         return 0;
  176 #undef IEEE80211_KEY_XR
  177 }
  178 
  179 /*
  180  * Set a net80211 key into the hardware.  This handles the
  181  * potential distribution of key state to multiple key
  182  * cache slots for TKIP with hardware MIC support.
  183  */
  184 int
  185 ath_keyset(struct ath_softc *sc, struct ieee80211vap *vap,
  186         const struct ieee80211_key *k,
  187         struct ieee80211_node *bss)
  188 {
  189         static const u_int8_t ciphermap[] = {
  190                 HAL_CIPHER_WEP,         /* IEEE80211_CIPHER_WEP */
  191                 HAL_CIPHER_TKIP,        /* IEEE80211_CIPHER_TKIP */
  192                 HAL_CIPHER_AES_OCB,     /* IEEE80211_CIPHER_AES_OCB */
  193                 HAL_CIPHER_AES_CCM,     /* IEEE80211_CIPHER_AES_CCM */
  194                 (u_int8_t) -1,          /* 4 is not allocated */
  195                 HAL_CIPHER_CKIP,        /* IEEE80211_CIPHER_CKIP */
  196                 HAL_CIPHER_CLR,         /* IEEE80211_CIPHER_NONE */
  197         };
  198         struct ath_hal *ah = sc->sc_ah;
  199         const struct ieee80211_cipher *cip = k->wk_cipher;
  200         u_int8_t gmac[IEEE80211_ADDR_LEN];
  201         const u_int8_t *mac;
  202         HAL_KEYVAL hk;
  203         int ret;
  204 
  205         memset(&hk, 0, sizeof(hk));
  206         /*
  207          * Software crypto uses a "clear key" so non-crypto
  208          * state kept in the key cache are maintained and
  209          * so that rx frames have an entry to match.
  210          */
  211         if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) {
  212                 KASSERT(cip->ic_cipher < nitems(ciphermap),
  213                         ("invalid cipher type %u", cip->ic_cipher));
  214                 hk.kv_type = ciphermap[cip->ic_cipher];
  215                 hk.kv_len = k->wk_keylen;
  216                 memcpy(hk.kv_val, k->wk_key, k->wk_keylen);
  217         } else
  218                 hk.kv_type = HAL_CIPHER_CLR;
  219 
  220         /*
  221          * If we're installing a clear cipher key and
  222          * the hardware doesn't support that, just succeed.
  223          * Leave it up to the net80211 layer to figure it out.
  224          */
  225         if (hk.kv_type == HAL_CIPHER_CLR && sc->sc_hasclrkey == 0) {
  226                 return (1);
  227         }
  228 
  229         /*
  230          * XXX TODO: check this:
  231          * 
  232          * Group keys on hardware that supports multicast frame
  233          * key search should only be done in adhoc/hostap mode,
  234          * not STA mode.
  235          *
  236          * XXX TODO: what about mesh, tdma?
  237          */
  238 #if 0
  239         if ((vap->iv_opmode == IEEE80211_M_HOSTAP ||
  240              vap->iv_opmode == IEEE80211_M_IBSS) &&
  241 #else
  242         if (
  243 #endif
  244             (k->wk_flags & IEEE80211_KEY_GROUP) &&
  245             sc->sc_mcastkey) {
  246                 /*
  247                  * Group keys on hardware that supports multicast frame
  248                  * key search use a MAC that is the sender's address with
  249                  * the multicast bit set instead of the app-specified address.
  250                  */
  251                 IEEE80211_ADDR_COPY(gmac, bss->ni_macaddr);
  252                 gmac[0] |= 0x01;
  253                 mac = gmac;
  254         } else
  255                 mac = k->wk_macaddr;
  256 
  257         ATH_LOCK(sc);
  258         ath_power_set_power_state(sc, HAL_PM_AWAKE);
  259         if (hk.kv_type == HAL_CIPHER_TKIP &&
  260             (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) {
  261                 ret = ath_keyset_tkip(sc, k, &hk, mac);
  262         } else {
  263                 KEYPRINTF(sc, k->wk_keyix, &hk, mac);
  264                 ret = ath_hal_keyset(ah, k->wk_keyix, &hk, mac);
  265         }
  266         ath_power_restore_power_state(sc);
  267         ATH_UNLOCK(sc);
  268 
  269         return (ret);
  270 }
  271 
  272 /*
  273  * Allocate tx/rx key slots for TKIP.  We allocate two slots for
  274  * each key, one for decrypt/encrypt and the other for the MIC.
  275  */
  276 static u_int16_t
  277 key_alloc_2pair(struct ath_softc *sc,
  278         ieee80211_keyix *txkeyix, ieee80211_keyix *rxkeyix)
  279 {
  280         u_int i, keyix;
  281 
  282         KASSERT(sc->sc_splitmic, ("key cache !split"));
  283         /* XXX could optimize */
  284         for (i = 0; i < nitems(sc->sc_keymap)/4; i++) {
  285                 u_int8_t b = sc->sc_keymap[i];
  286                 if (b != 0xff) {
  287                         /*
  288                          * One or more slots in this byte are free.
  289                          */
  290                         keyix = i*NBBY;
  291                         while (b & 1) {
  292                 again:
  293                                 keyix++;
  294                                 b >>= 1;
  295                         }
  296                         /* XXX IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV */
  297                         if (isset(sc->sc_keymap, keyix+32) ||
  298                             isset(sc->sc_keymap, keyix+64) ||
  299                             isset(sc->sc_keymap, keyix+32+64)) {
  300                                 /* full pair unavailable */
  301                                 /* XXX statistic */
  302                                 if (keyix == (i+1)*NBBY) {
  303                                         /* no slots were appropriate, advance */
  304                                         continue;
  305                                 }
  306                                 goto again;
  307                         }
  308                         setbit(sc->sc_keymap, keyix);
  309                         setbit(sc->sc_keymap, keyix+64);
  310                         setbit(sc->sc_keymap, keyix+32);
  311                         setbit(sc->sc_keymap, keyix+32+64);
  312                         DPRINTF(sc, ATH_DEBUG_KEYCACHE,
  313                                 "%s: key pair %u,%u %u,%u\n",
  314                                 __func__, keyix, keyix+64,
  315                                 keyix+32, keyix+32+64);
  316                         *txkeyix = keyix;
  317                         *rxkeyix = keyix+32;
  318                         return 1;
  319                 }
  320         }
  321         DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: out of pair space\n", __func__);
  322         return 0;
  323 }
  324 
  325 /*
  326  * Allocate tx/rx key slots for TKIP.  We allocate two slots for
  327  * each key, one for decrypt/encrypt and the other for the MIC.
  328  */
  329 static u_int16_t
  330 key_alloc_pair(struct ath_softc *sc,
  331         ieee80211_keyix *txkeyix, ieee80211_keyix *rxkeyix)
  332 {
  333         u_int i, keyix;
  334 
  335         KASSERT(!sc->sc_splitmic, ("key cache split"));
  336         /* XXX could optimize */
  337         for (i = 0; i < nitems(sc->sc_keymap)/4; i++) {
  338                 u_int8_t b = sc->sc_keymap[i];
  339                 if (b != 0xff) {
  340                         /*
  341                          * One or more slots in this byte are free.
  342                          */
  343                         keyix = i*NBBY;
  344                         while (b & 1) {
  345                 again:
  346                                 keyix++;
  347                                 b >>= 1;
  348                         }
  349                         if (isset(sc->sc_keymap, keyix+64)) {
  350                                 /* full pair unavailable */
  351                                 /* XXX statistic */
  352                                 if (keyix == (i+1)*NBBY) {
  353                                         /* no slots were appropriate, advance */
  354                                         continue;
  355                                 }
  356                                 goto again;
  357                         }
  358                         setbit(sc->sc_keymap, keyix);
  359                         setbit(sc->sc_keymap, keyix+64);
  360                         DPRINTF(sc, ATH_DEBUG_KEYCACHE,
  361                                 "%s: key pair %u,%u\n",
  362                                 __func__, keyix, keyix+64);
  363                         *txkeyix = *rxkeyix = keyix;
  364                         return 1;
  365                 }
  366         }
  367         DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: out of pair space\n", __func__);
  368         return 0;
  369 }
  370 
  371 /*
  372  * Allocate a single key cache slot.
  373  */
  374 static int
  375 key_alloc_single(struct ath_softc *sc,
  376         ieee80211_keyix *txkeyix, ieee80211_keyix *rxkeyix)
  377 {
  378         u_int i, keyix;
  379 
  380         if (sc->sc_hasclrkey == 0) {
  381                 /*
  382                  * Map to slot 0 for the AR5210.
  383                  */
  384                 *txkeyix = *rxkeyix = 0;
  385                 return (1);
  386         }
  387 
  388         /* XXX try i,i+32,i+64,i+32+64 to minimize key pair conflicts */
  389         for (i = 0; i < nitems(sc->sc_keymap); i++) {
  390                 u_int8_t b = sc->sc_keymap[i];
  391                 if (b != 0xff) {
  392                         /*
  393                          * One or more slots are free.
  394                          */
  395                         keyix = i*NBBY;
  396                         while (b & 1)
  397                                 keyix++, b >>= 1;
  398                         setbit(sc->sc_keymap, keyix);
  399                         DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: key %u\n",
  400                                 __func__, keyix);
  401                         *txkeyix = *rxkeyix = keyix;
  402                         return 1;
  403                 }
  404         }
  405         DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: out of space\n", __func__);
  406         return 0;
  407 }
  408 
  409 /*
  410  * Allocate one or more key cache slots for a uniacst key.  The
  411  * key itself is needed only to identify the cipher.  For hardware
  412  * TKIP with split cipher+MIC keys we allocate two key cache slot
  413  * pairs so that we can setup separate TX and RX MIC keys.  Note
  414  * that the MIC key for a TKIP key at slot i is assumed by the
  415  * hardware to be at slot i+64.  This limits TKIP keys to the first
  416  * 64 entries.
  417  */
  418 int
  419 ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
  420         ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
  421 {
  422         struct ath_softc *sc = vap->iv_ic->ic_softc;
  423 
  424         /*
  425          * Group key allocation must be handled specially for
  426          * parts that do not support multicast key cache search
  427          * functionality.  For those parts the key id must match
  428          * the h/w key index so lookups find the right key.  On
  429          * parts w/ the key search facility we install the sender's
  430          * mac address (with the high bit set) and let the hardware
  431          * find the key w/o using the key id.  This is preferred as
  432          * it permits us to support multiple users for adhoc and/or
  433          * multi-station operation.
  434          */
  435         if (k->wk_keyix != IEEE80211_KEYIX_NONE) {
  436                 /*
  437                  * Only global keys should have key index assigned.
  438                  */
  439                 if (!(&vap->iv_nw_keys[0] <= k &&
  440                       k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) {
  441                         /* should not happen */
  442                         DPRINTF(sc, ATH_DEBUG_KEYCACHE,
  443                                 "%s: bogus group key\n", __func__);
  444                         return 0;
  445                 }
  446                 if (vap->iv_opmode != IEEE80211_M_HOSTAP ||
  447                     !(k->wk_flags & IEEE80211_KEY_GROUP) ||
  448                     !sc->sc_mcastkey) {
  449                         /*
  450                          * XXX we pre-allocate the global keys so
  451                          * have no way to check if they've already
  452                          * been allocated.
  453                          */
  454                         *keyix = *rxkeyix =
  455                             ieee80211_crypto_get_key_wepidx(vap, k);
  456                         return 1;
  457                 }
  458                 /*
  459                  * Group key and device supports multicast key search.
  460                  */
  461                 k->wk_keyix = IEEE80211_KEYIX_NONE;
  462         }
  463 
  464         /*
  465          * We allocate two pair for TKIP when using the h/w to do
  466          * the MIC.  For everything else, including software crypto,
  467          * we allocate a single entry.  Note that s/w crypto requires
  468          * a pass-through slot on the 5211 and 5212.  The 5210 does
  469          * not support pass-through cache entries and we map all
  470          * those requests to slot 0.
  471          */
  472         if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
  473                 return key_alloc_single(sc, keyix, rxkeyix);
  474         } else if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP &&
  475             (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) {
  476                 if (sc->sc_splitmic)
  477                         return key_alloc_2pair(sc, keyix, rxkeyix);
  478                 else
  479                         return key_alloc_pair(sc, keyix, rxkeyix);
  480         } else {
  481                 return key_alloc_single(sc, keyix, rxkeyix);
  482         }
  483 }
  484 
  485 /*
  486  * Delete an entry in the key cache allocated by ath_key_alloc.
  487  */
  488 int
  489 ath_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
  490 {
  491         struct ath_softc *sc = vap->iv_ic->ic_softc;
  492         struct ath_hal *ah = sc->sc_ah;
  493         const struct ieee80211_cipher *cip = k->wk_cipher;
  494         u_int keyix = k->wk_keyix;
  495 
  496         DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: delete key %u\n", __func__, keyix);
  497 
  498         ATH_LOCK(sc);
  499         ath_power_set_power_state(sc, HAL_PM_AWAKE);
  500         ath_hal_keyreset(ah, keyix);
  501         /*
  502          * Handle split tx/rx keying required for TKIP with h/w MIC.
  503          */
  504         if (cip->ic_cipher == IEEE80211_CIPHER_TKIP &&
  505             (k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && sc->sc_splitmic)
  506                 ath_hal_keyreset(ah, keyix+32);         /* RX key */
  507         if (keyix >= IEEE80211_WEP_NKID) {
  508                 /*
  509                  * Don't touch keymap entries for global keys so
  510                  * they are never considered for dynamic allocation.
  511                  */
  512                 clrbit(sc->sc_keymap, keyix);
  513                 if (cip->ic_cipher == IEEE80211_CIPHER_TKIP &&
  514                     (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) {
  515                         clrbit(sc->sc_keymap, keyix+64);        /* TX key MIC */
  516                         if (sc->sc_splitmic) {
  517                                 /* +32 for RX key, +32+64 for RX key MIC */
  518                                 clrbit(sc->sc_keymap, keyix+32);
  519                                 clrbit(sc->sc_keymap, keyix+32+64);
  520                         }
  521                 }
  522         }
  523         ath_power_restore_power_state(sc);
  524         ATH_UNLOCK(sc);
  525         return 1;
  526 }
  527 
  528 /*
  529  * Set the key cache contents for the specified key.  Key cache
  530  * slot(s) must already have been allocated by ath_key_alloc.
  531  */
  532 int
  533 ath_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
  534 {
  535         struct ath_softc *sc = vap->iv_ic->ic_softc;
  536 
  537         return ath_keyset(sc, vap, k, vap->iv_bss);
  538 }

Cache object: 28b8b333c5b7bafea781847bda7377f7


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