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_spectral.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) 2013 Adrian Chadd <adrian@FreeBSD.org>
    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  * $FreeBSD$
   32  */
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD$");
   35 
   36 /*
   37  * Implement some basic spectral scan control logic.
   38  */
   39 #include "opt_ath.h"
   40 #include "opt_inet.h"
   41 #include "opt_wlan.h"
   42 
   43 #include <sys/param.h>
   44 #include <sys/systm.h> 
   45 #include <sys/sysctl.h>
   46 #include <sys/kernel.h>
   47 #include <sys/lock.h>
   48 #include <sys/malloc.h>
   49 #include <sys/mutex.h>
   50 #include <sys/errno.h>
   51 
   52 #include <machine/bus.h>
   53 #include <machine/resource.h>
   54 #include <sys/bus.h>
   55 
   56 #include <sys/socket.h>
   57 
   58 #include <net/if.h>
   59 #include <net/if_var.h>
   60 #include <net/if_media.h>
   61 #include <net/if_arp.h>
   62 #include <net/ethernet.h>               /* XXX for ether_sprintf */
   63 
   64 #include <net80211/ieee80211_var.h>
   65 
   66 #include <net/bpf.h>
   67 
   68 #ifdef INET
   69 #include <netinet/in.h>
   70 #include <netinet/if_ether.h>
   71 #endif
   72 
   73 #include <dev/ath/if_athvar.h>
   74 #include <dev/ath/if_ath_spectral.h>
   75 #include <dev/ath/if_ath_misc.h>
   76 
   77 #include <dev/ath/ath_hal/ah_desc.h>
   78 
   79 struct ath_spectral_state {
   80         HAL_SPECTRAL_PARAM      spectral_state;
   81 
   82         /*
   83          * Should we enable spectral scan upon
   84          * each network interface reset/change?
   85          *
   86          * This is intended to allow spectral scan
   87          * frame reporting during channel scans.
   88          *
   89          * Later on it can morph into a larger
   90          * scale config method where it pushes
   91          * a "channel scan" config into the hardware
   92          * rather than just the spectral_state
   93          * config.
   94          */
   95         int spectral_enable_after_reset;
   96 };
   97 
   98 /*
   99  * Methods which are required
  100  */
  101 
  102 /*
  103  * Attach spectral to the given interface
  104  */
  105 int
  106 ath_spectral_attach(struct ath_softc *sc)
  107 {
  108         struct ath_spectral_state *ss;
  109 
  110         /*
  111          * If spectral isn't supported, don't error - just
  112          * quietly complete.
  113          */
  114         if (! ath_hal_spectral_supported(sc->sc_ah))
  115                 return (0);
  116 
  117         ss = malloc(sizeof(struct ath_spectral_state),
  118             M_TEMP, M_WAITOK | M_ZERO);
  119 
  120         if (ss == NULL) {
  121                 device_printf(sc->sc_dev, "%s: failed to alloc memory\n",
  122                     __func__);
  123                 return (-ENOMEM);
  124         }
  125 
  126         sc->sc_spectral = ss;
  127 
  128         (void) ath_hal_spectral_get_config(sc->sc_ah, &ss->spectral_state);
  129 
  130         return (0);
  131 }
  132 
  133 /*
  134  * Detach spectral from the given interface
  135  */
  136 int
  137 ath_spectral_detach(struct ath_softc *sc)
  138 {
  139 
  140         if (! ath_hal_spectral_supported(sc->sc_ah))
  141                 return (0);
  142 
  143         if (sc->sc_spectral != NULL) {
  144                 free(sc->sc_spectral, M_TEMP);
  145         }
  146         return (0);
  147 }
  148 
  149 /*
  150  * Check whether spectral needs enabling and if so,
  151  * flip it on.
  152  */
  153 int
  154 ath_spectral_enable(struct ath_softc *sc, struct ieee80211_channel *ch)
  155 {
  156         struct ath_spectral_state *ss = sc->sc_spectral;
  157 
  158         /* Default to disable spectral PHY reporting */
  159         sc->sc_dospectral = 0;
  160 
  161         if (ss == NULL)
  162                 return (0);
  163 
  164         if (ss->spectral_enable_after_reset) {
  165                 ath_hal_spectral_configure(sc->sc_ah,
  166                     &ss->spectral_state);
  167                 (void) ath_hal_spectral_start(sc->sc_ah);
  168                 sc->sc_dospectral = 1;
  169         }
  170         return (0);
  171 }
  172 
  173 /*
  174  * Handle ioctl requests from the diagnostic interface.
  175  *
  176  * The initial part of this code resembles ath_ioctl_diag();
  177  * it's likely a good idea to reduce duplication between
  178  * these two routines.
  179  */
  180 int
  181 ath_ioctl_spectral(struct ath_softc *sc, struct ath_diag *ad)
  182 {
  183         unsigned int id = ad->ad_id & ATH_DIAG_ID;
  184         void *indata = NULL;
  185         void *outdata = NULL;
  186         u_int32_t insize = ad->ad_in_size;
  187         u_int32_t outsize = ad->ad_out_size;
  188         int error = 0;
  189         HAL_SPECTRAL_PARAM peout;
  190         HAL_SPECTRAL_PARAM *pe;
  191         struct ath_spectral_state *ss = sc->sc_spectral;
  192         int val;
  193 
  194         if (! ath_hal_spectral_supported(sc->sc_ah))
  195                 return (EINVAL);
  196 
  197         ATH_LOCK(sc);
  198         ath_power_set_power_state(sc, HAL_PM_AWAKE);
  199         ATH_UNLOCK(sc);
  200 
  201         if (ad->ad_id & ATH_DIAG_IN) {
  202                 /*
  203                  * Copy in data.
  204                  */
  205                 indata = malloc(insize, M_TEMP, M_NOWAIT);
  206                 if (indata == NULL) {
  207                         error = ENOMEM;
  208                         goto bad;
  209                 }
  210                 error = copyin(ad->ad_in_data, indata, insize);
  211                 if (error)
  212                         goto bad;
  213         }
  214         if (ad->ad_id & ATH_DIAG_DYN) {
  215                 /*
  216                  * Allocate a buffer for the results (otherwise the HAL
  217                  * returns a pointer to a buffer where we can read the
  218                  * results).  Note that we depend on the HAL leaving this
  219                  * pointer for us to use below in reclaiming the buffer;
  220                  * may want to be more defensive.
  221                  */
  222                 outdata = malloc(outsize, M_TEMP, M_NOWAIT | M_ZERO);
  223                 if (outdata == NULL) {
  224                         error = ENOMEM;
  225                         goto bad;
  226                 }
  227         }
  228         switch (id) {
  229                 case SPECTRAL_CONTROL_GET_PARAMS:
  230                         memset(&peout, 0, sizeof(peout));
  231                         outsize = sizeof(HAL_SPECTRAL_PARAM);
  232                         ath_hal_spectral_get_config(sc->sc_ah, &peout);
  233                         pe = (HAL_SPECTRAL_PARAM *) outdata;
  234                         memcpy(pe, &peout, sizeof(*pe));
  235                         break;
  236                 case SPECTRAL_CONTROL_SET_PARAMS:
  237                         if (insize < sizeof(HAL_SPECTRAL_PARAM)) {
  238                                 error = EINVAL;
  239                                 break;
  240                         }
  241                         pe = (HAL_SPECTRAL_PARAM *) indata;
  242                         ath_hal_spectral_configure(sc->sc_ah, pe);
  243                         /* Save a local copy of the updated parameters */
  244                         ath_hal_spectral_get_config(sc->sc_ah,
  245                             &ss->spectral_state);
  246                         break;
  247                 case SPECTRAL_CONTROL_START:
  248                         ath_hal_spectral_configure(sc->sc_ah,
  249                             &ss->spectral_state);
  250                         (void) ath_hal_spectral_start(sc->sc_ah);
  251                         sc->sc_dospectral = 1;
  252                         /* XXX need to update the PHY mask in the driver */
  253                         break;
  254                 case SPECTRAL_CONTROL_STOP:
  255                         (void) ath_hal_spectral_stop(sc->sc_ah);
  256                         sc->sc_dospectral = 0;
  257                         /* XXX need to update the PHY mask in the driver */
  258                         break;
  259                 case SPECTRAL_CONTROL_ENABLE_AT_RESET:
  260                         if (insize < sizeof(int)) {
  261                                 device_printf(sc->sc_dev, "%d != %d\n",
  262                                     insize,
  263                                     (int) sizeof(int));
  264                                 error = EINVAL;
  265                                 break;
  266                         }
  267                         if (indata == NULL) {
  268                                 device_printf(sc->sc_dev, "indata=NULL\n");
  269                                 error = EINVAL;
  270                                 break;
  271                         }
  272                         val = * ((int *) indata);
  273                         if (val == 0)
  274                                 ss->spectral_enable_after_reset = 0;
  275                         else
  276                                 ss->spectral_enable_after_reset = 1;
  277                         break;
  278                 case SPECTRAL_CONTROL_ENABLE:
  279                         /* XXX TODO */
  280                 case SPECTRAL_CONTROL_DISABLE:
  281                         /* XXX TODO */
  282                 break;
  283                 default:
  284                         error = EINVAL;
  285                         goto bad;
  286         }
  287         if (outsize < ad->ad_out_size)
  288                 ad->ad_out_size = outsize;
  289         if (outdata && copyout(outdata, ad->ad_out_data, ad->ad_out_size))
  290                 error = EFAULT;
  291 bad:
  292         if ((ad->ad_id & ATH_DIAG_IN) && indata != NULL)
  293                 free(indata, M_TEMP);
  294         if ((ad->ad_id & ATH_DIAG_DYN) && outdata != NULL)
  295                 free(outdata, M_TEMP);
  296         ATH_LOCK(sc);
  297         ath_power_restore_power_state(sc);
  298         ATH_UNLOCK(sc);
  299 
  300         return (error);
  301 }

Cache object: 66e11e95db2dd07ba1deeb6fabced118


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