/*
 * Copyright (c) 2002-2014, 2016-2017 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/*===========================================================================

                                 dfs_init.c

  OVERVIEW:

  Source code borrowed from QCA_MAIN DFS module

  DEPENDENCIES:

  Are listed for each API below.

===========================================================================*/

/*===========================================================================

                      EDIT HISTORY FOR FILE


  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.



  when        who     what, where, why
----------    ---    --------------------------------------------------------

===========================================================================*/

#include "dfs.h"
/* TO DO DFS
#include <ieee80211_var.h>
*/
#ifdef ATH_SUPPORT_DFS

extern int domainoverride;

/*
 * Clear all delay lines for all filter types
 *
 * This may be called before any radar pulses are configured
 * (eg on a non-DFS channel, with radar PHY errors still showing up.)
 * In that case, just drop out early.
 */
void dfs_reset_alldelaylines(struct ath_dfs *dfs)
{
        struct dfs_filtertype *ft = NULL;
        struct dfs_filter *rf;
        struct dfs_delayline *dl;
        struct dfs_pulseline *pl;
        int i,j;

        if (dfs == NULL) {
            VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                                "%s[%d]: sc_dfs is NULL", __func__, __LINE__);
            return;
        }
        pl = dfs->pulses;

        if (pl == NULL) {
            VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                            "%s[%d]:  pl==NULL, dfs=%pK", __func__, __LINE__, dfs);
            return;
        }

        if (dfs->dfs_b5radars == NULL) {
            VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
            "%s[%d]: pl==NULL, b5radars=%pK", __func__, __LINE__, dfs->dfs_b5radars);
            return;
        }

         /* reset the pulse log */
        pl->pl_firstelem = pl->pl_numelems = 0;
        pl->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK;

        for (i=0; i<DFS_MAX_RADAR_TYPES; i++) {
            if (dfs->dfs_radarf[i] != NULL) {
                ft = dfs->dfs_radarf[i];
                if (NULL != ft) {
                    for (j = 0; j < ft->ft_numfilters; j++) {
                        rf = ft->ft_filters[j];
                        dl = &(rf->rf_dl);
                        if (dl != NULL) {
                            OS_MEMZERO(dl, sizeof(struct dfs_delayline));
                            dl->dl_lastelem = (0xFFFFFFFF) & DFS_MAX_DL_MASK;
                        }
                    }
                }
            }
        }
        for (i = 0; i < DFS_MAX_RADAR_TYPES; i++) {
            if (dfs->dfs_dc_radarf[i] == NULL)
                continue;

            ft = dfs->dfs_dc_radarf[i];
            for (j = 0; j < ft->ft_numfilters; j++) {
                rf = ft->ft_filters[j];
                dl = &(rf->rf_dl);
                if (dl == NULL)
                    continue;

                OS_MEMZERO(dl, sizeof(struct dfs_delayline));
                dl->dl_lastelem = (0xFFFFFFFF) & DFS_MAX_DL_MASK;
            }
        }

        for (i = 0; i < dfs->dfs_rinfo.rn_numbin5radars; i++) {
            OS_MEMZERO(&(dfs->dfs_b5radars[i].br_elems[0]), sizeof(struct dfs_bin5elem)*DFS_MAX_B5_SIZE);
            dfs->dfs_b5radars[i].br_firstelem = 0;
            dfs->dfs_b5radars[i].br_numelems = 0;
            dfs->dfs_b5radars[i].br_lastelem = (0xFFFFFFFF)&DFS_MAX_B5_MASK;
        }
}
/*
 * Clear only a single delay line
 */

void dfs_reset_delayline(struct dfs_delayline *dl)
{
   OS_MEMZERO(&(dl->dl_elems[0]), sizeof(dl->dl_elems));
   dl->dl_lastelem = (0xFFFFFFFF)&DFS_MAX_DL_MASK;
}

void dfs_reset_filter_delaylines(struct dfs_filtertype *dft)
{
        int i;
        struct dfs_filter *df;
        for (i=0; i< DFS_MAX_NUM_RADAR_FILTERS; i++) {
                df = dft->ft_filters[i];
                dfs_reset_delayline(&(df->rf_dl));
        }
}

void
dfs_reset_radarq(struct ath_dfs *dfs)
{
   struct dfs_event *event;
   if (dfs == NULL) {
      DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: sc_dfs is NULL", __func__);
      return;
   }
   ATH_DFSQ_LOCK(dfs);
   ATH_DFSEVENTQ_LOCK(dfs);
   while (!STAILQ_EMPTY(&(dfs->dfs_radarq))) {
      event = STAILQ_FIRST(&(dfs->dfs_radarq));
      STAILQ_REMOVE_HEAD(&(dfs->dfs_radarq), re_list);
      OS_MEMZERO(event, sizeof(struct dfs_event));
      STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), event, re_list);
   }
   ATH_DFSEVENTQ_UNLOCK(dfs);
   ATH_DFSQ_UNLOCK(dfs);
}


/* This function Initialize the radar filter tables
 * if the ath dfs domain is uninitalized or
 *    ath dfs domain is different from hal dfs domain
 */
int dfs_init_radar_filters(struct ieee80211com *ic,
  struct ath_dfs_radar_tab_info *radar_info)
{
    u_int32_t T, Tmax;
    int numpulses,p,n, i;
    int numradars = 0, numb5radars = 0;
    struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs;
    struct dfs_filtertype *ft = NULL;
    struct dfs_filter *rf=NULL;
    struct dfs_pulse *dfs_radars;
    struct dfs_bin5pulse *b5pulses=NULL;
    int32_t min_rssithresh=DFS_MAX_RSSI_VALUE;
    u_int32_t max_pulsedur=0;

    if (dfs == NULL) {
        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                        "%s[%d]: dfs is NULL", __func__, __LINE__);
        return DFS_STATUS_FAIL;
    }
    /* clear up the dfs domain flag first */
#ifndef ATH_DFS_RADAR_DETECTION_ONLY
    dfs->ath_dfs_isdfsregdomain = 0;
#endif

    /*
     * If radar_info is NULL or dfsdomain is NULL, treat
     * the rest of the radar configuration as suspect.
     */
    if (radar_info == NULL || radar_info->dfsdomain == 0) {
        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                        "%s[%d]: Unknown dfs domain %d ",
                        __func__, __LINE__, dfs->dfsdomain);
        /* Disable radar detection since we don't have a radar domain */
        dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN;
        /* Returning success though we are not completing init. A failure
         * will fail dfs_attach also.
         */
        return DFS_STATUS_SUCCESS;
    }

    VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
                    "%s[%d]:dfsdomain=%d, numradars=%d, numb5radars=%d",
                    __func__, __LINE__, radar_info->dfsdomain,
                    radar_info->numradars, radar_info->numb5radars);
    dfs->dfsdomain = radar_info->dfsdomain;
    dfs_radars = radar_info->dfs_radars;
    numradars = radar_info->numradars;
    b5pulses = radar_info->b5pulses;
    numb5radars = radar_info->numb5radars;

    /* XXX this should be an explicit copy of some sort! */
    dfs->dfs_defaultparams = radar_info->dfs_defaultparams;

#ifndef ATH_DFS_RADAR_DETECTION_ONLY
    dfs->ath_dfs_isdfsregdomain = 1;
#endif

    dfs->dfs_rinfo.rn_numradars = 0;
    /* Clear filter type table */
    for (n = 0; n < 256; n++) {
        for (i=0;i<DFS_MAX_RADAR_OVERLAP; i++)
            (dfs->dfs_radartable[n])[i] = -1;
    }
    /* Clear dc filter type table */
    for (n = 0; n < 256; n++) {
        for (i = 0;i < DFS_MAX_RADAR_OVERLAP; i++)
            (dfs->dfs_dc_radartable[n])[i] = -1;
    }

    /* Now, initialize the radar filters */
    for (p=0; p<numradars; p++) {
    ft = NULL;
    for (n=0; n<dfs->dfs_rinfo.rn_numradars; n++) {
        if ((dfs_radars[p].rp_pulsedur == dfs->dfs_radarf[n]->ft_filterdur) &&
           (dfs_radars[p].rp_numpulses == dfs->dfs_radarf[n]->ft_numpulses) &&
           (dfs_radars[p].rp_mindur == dfs->dfs_radarf[n]->ft_mindur) &&
           (dfs_radars[p].rp_maxdur == dfs->dfs_radarf[n]->ft_maxdur)) {
           ft = dfs->dfs_radarf[n];
           break;
        }
    }
    if (ft == NULL) {
        /* No filter of the appropriate dur was found */
        if ((dfs->dfs_rinfo.rn_numradars+1) >DFS_MAX_RADAR_TYPES) {
         DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: Too many filter types",
         __func__);
         goto bad4;
        }
        ft = dfs->dfs_radarf[dfs->dfs_rinfo.rn_numradars];
        ft->ft_numfilters = 0;
        ft->ft_numpulses = dfs_radars[p].rp_numpulses;
        ft->ft_patterntype = dfs_radars[p].rp_patterntype;
        ft->ft_mindur = dfs_radars[p].rp_mindur;
        ft->ft_maxdur = dfs_radars[p].rp_maxdur;
        ft->ft_filterdur = dfs_radars[p].rp_pulsedur;
        ft->ft_rssithresh = dfs_radars[p].rp_rssithresh;
        ft->ft_rssimargin = dfs_radars[p].rp_rssimargin;
        ft->ft_minpri = 1000000;

        if (ft->ft_rssithresh < min_rssithresh)
        min_rssithresh = ft->ft_rssithresh;
        if (ft->ft_maxdur > max_pulsedur)
        max_pulsedur = ft->ft_maxdur;
        for (i=ft->ft_mindur; i<=ft->ft_maxdur; i++) {
               u_int32_t stop=0,tableindex=0;
               while ((tableindex < DFS_MAX_RADAR_OVERLAP) && (!stop)) {
                   if ((dfs->dfs_radartable[i])[tableindex] == -1)
                  stop = 1;
                   else
                  tableindex++;
               }
               if (stop) {
                   (dfs->dfs_radartable[i])[tableindex] =
                  (int8_t) (dfs->dfs_rinfo.rn_numradars);
               } else {
                   DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
                  "%s: Too many overlapping radar filters",
                  __func__);
                   goto bad4;
               }
        }
        dfs->dfs_rinfo.rn_numradars++;
    }
    rf = ft->ft_filters[ft->ft_numfilters++];
    dfs_reset_delayline(&rf->rf_dl);
    numpulses = dfs_radars[p].rp_numpulses;

    rf->rf_numpulses = numpulses;
    rf->rf_patterntype = dfs_radars[p].rp_patterntype;
    rf->rf_sidx_spread = dfs_radars[p].rp_sidx_spread;
    rf->rf_check_delta_peak = dfs_radars[p].rp_check_delta_peak;
    rf->rf_pulseid = dfs_radars[p].rp_pulseid;
    rf->rf_mindur = dfs_radars[p].rp_mindur;
    rf->rf_maxdur = dfs_radars[p].rp_maxdur;
    rf->rf_numpulses = dfs_radars[p].rp_numpulses;
    rf->rf_ignore_pri_window = dfs_radars[p].rp_ignore_pri_window;
    T = (100000000/dfs_radars[p].rp_max_pulsefreq) -
         100*(dfs_radars[p].rp_meanoffset);
            rf->rf_minpri =
            dfs_round((int32_t)T - (100*(dfs_radars[p].rp_pulsevar)));
    Tmax = (100000000/dfs_radars[p].rp_pulsefreq) -
            100*(dfs_radars[p].rp_meanoffset);
      rf->rf_maxpri =
         dfs_round((int32_t)Tmax + (100*(dfs_radars[p].rp_pulsevar)));

        if( rf->rf_minpri < ft->ft_minpri )
        ft->ft_minpri = rf->rf_minpri;

    rf->rf_fixed_pri_radar_pulse = ( dfs_radars[p].rp_max_pulsefreq == dfs_radars[p].rp_pulsefreq ) ? 1 : 0;
    rf->rf_threshold = dfs_radars[p].rp_threshold;
    rf->rf_filterlen = rf->rf_maxpri * rf->rf_numpulses;

    VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]: minprf = %d maxprf = %d pulsevar = %d thresh=%d",
            __func__,__LINE__,dfs_radars[p].rp_pulsefreq, dfs_radars[p].rp_max_pulsefreq,
            dfs_radars[p].rp_pulsevar, rf->rf_threshold);
    VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]:minpri = %d maxpri = %d filterlen = %d filterID = %d",__func__,__LINE__,
            rf->rf_minpri, rf->rf_maxpri, rf->rf_filterlen, rf->rf_pulseid);

    }

    /* Initialize dc radar filters */
    for (p = 0; p < numradars; p++) {
        ft = NULL;
        for (n = 0; n < dfs->dfs_rinfo.rn_numradars; n++) {
            if ((dfs_radars[p].rp_pulsedur ==
                     dfs->dfs_dc_radarf[n]->ft_filterdur) &&
                (dfs_radars[p].rp_numpulses ==
                     dfs->dfs_dc_radarf[n]->ft_numpulses) &&
                (dfs_radars[p].rp_mindur == dfs->dfs_dc_radarf[n]->ft_mindur) &&
                (dfs_radars[p].rp_maxdur == dfs->dfs_dc_radarf[n]->ft_maxdur)) {

                ft = dfs->dfs_dc_radarf[n];
                break;
            }
        }
        if (ft == NULL) {
            /* No filter of the appropriate dur was found */
            if ((dfs->dfs_rinfo.rn_numradars+1) > DFS_MAX_RADAR_TYPES) {
                DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: Too many filter types",
                        __func__);
                goto bad4;
            }
            ft = dfs->dfs_dc_radarf[dfs->dfs_rinfo.rn_numradars];
            ft->ft_numfilters = 0;
            ft->ft_numpulses = dfs_radars[p].rp_numpulses;
            ft->ft_patterntype = dfs_radars[p].rp_patterntype;
            ft->ft_mindur = dfs_radars[p].rp_mindur;
            ft->ft_maxdur = dfs_radars[p].rp_maxdur;
            ft->ft_filterdur = dfs_radars[p].rp_pulsedur;
            ft->ft_rssithresh = dfs_radars[p].rp_rssithresh;
            ft->ft_rssimargin = dfs_radars[p].rp_rssimargin;
            ft->ft_minpri = DFS_FILTER_DEFAULT_PRI;

            if (ft->ft_rssithresh < min_rssithresh)
                min_rssithresh = ft->ft_rssithresh;
            if (ft->ft_maxdur > max_pulsedur)
                max_pulsedur = ft->ft_maxdur;
            for (i = ft->ft_mindur; i <= ft->ft_maxdur; i++) {
                u_int32_t stop = 0, tableindex = 0;

                while ((tableindex < DFS_MAX_RADAR_OVERLAP) && (!stop)) {
                    if ((dfs->dfs_dc_radartable[i])[tableindex] == -1)
                        stop = 1;
                    else
                        tableindex++;
                }
                if (stop) {
                    (dfs->dfs_dc_radartable[i])[tableindex] =
                        (int8_t) (dfs->dfs_rinfo.rn_numradars);
                } else {
                    DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
                            "%s: Too many overlapping dc radar filters",
                            __func__);
                    goto bad4;
               }
            }
            dfs->dfs_rinfo.rn_numradars++;
        }
        rf = ft->ft_filters[ft->ft_numfilters++];
        dfs_reset_delayline(&rf->rf_dl);
        numpulses = dfs_radars[p].rp_numpulses;

        rf->rf_numpulses = numpulses;
        rf->rf_patterntype = dfs_radars[p].rp_patterntype;
        rf->rf_sidx_spread = dfs_radars[p].rp_sidx_spread;
        rf->rf_check_delta_peak = dfs_radars[p].rp_check_delta_peak;
        rf->rf_pulseid = dfs_radars[p].rp_pulseid;
        rf->rf_mindur = dfs_radars[p].rp_mindur;
        rf->rf_maxdur = dfs_radars[p].rp_maxdur;
        rf->rf_numpulses = dfs_radars[p].rp_numpulses;
        rf->rf_ignore_pri_window = dfs_radars[p].rp_ignore_pri_window;
        T = (100000000/dfs_radars[p].rp_max_pulsefreq) -
            100*(dfs_radars[p].rp_meanoffset);
        rf->rf_minpri =
            dfs_round((int32_t)T - (100*(dfs_radars[p].rp_pulsevar)));
        Tmax = (100000000/dfs_radars[p].rp_pulsefreq) -
            100*(dfs_radars[p].rp_meanoffset);
        rf->rf_maxpri =
            dfs_round((int32_t)Tmax + (100*(dfs_radars[p].rp_pulsevar)));

        if(rf->rf_minpri < ft->ft_minpri)
            ft->ft_minpri = rf->rf_minpri;

        rf->rf_fixed_pri_radar_pulse =
                (dfs_radars[p].rp_max_pulsefreq ==
                    dfs_radars[p].rp_pulsefreq) ? 1 : 0;
        /* for pulseid 5, increase threshould by 1 */
        if (dfs_radars[p].rp_pulseid == 5)
            rf->rf_threshold = dfs_radars[p].rp_threshold + 1;
        else
            rf->rf_threshold = dfs_radars[p].rp_threshold;

        rf->rf_filterlen = rf->rf_maxpri * rf->rf_numpulses;

        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]: minprf = %d maxprf = %d pulsevar = %d thresh=%d",
                __func__, __LINE__, dfs_radars[p].rp_pulsefreq,
                dfs_radars[p].rp_max_pulsefreq, dfs_radars[p].rp_pulsevar,
                rf->rf_threshold);
        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]:minpri = %d maxpri = %d filterlen = %d filterID = %d",
                __func__, __LINE__, rf->rf_minpri, rf->rf_maxpri,
                rf->rf_filterlen, rf->rf_pulseid);

    }
#ifdef DFS_DEBUG
    dfs_print_filters(dfs);
#endif
    dfs->dfs_rinfo.rn_numbin5radars  = numb5radars;
    if (dfs->dfs_b5radars != NULL)
        OS_FREE(dfs->dfs_b5radars);

    dfs->dfs_b5radars = (struct dfs_bin5radars *)OS_MALLOC(NULL,
      numb5radars * sizeof(struct dfs_bin5radars), GFP_KERNEL);
    if (dfs->dfs_b5radars == NULL) {
        DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
        "%s: cannot allocate memory for bin5 radars",
        __func__);
        goto bad4;
    }
    for (n=0; n<numb5radars; n++) {
        dfs->dfs_b5radars[n].br_pulse = b5pulses[n];
        dfs->dfs_b5radars[n].br_pulse.b5_timewindow *= 1000000;
        if (dfs->dfs_b5radars[n].br_pulse.b5_rssithresh < min_rssithresh)
            min_rssithresh = dfs->dfs_b5radars[n].br_pulse.b5_rssithresh;
        if (dfs->dfs_b5radars[n].br_pulse.b5_maxdur > max_pulsedur)
            max_pulsedur = dfs->dfs_b5radars[n].br_pulse.b5_maxdur;
    }
    dfs_reset_alldelaylines(dfs);
    dfs_reset_radarq(dfs);
    dfs->dfs_curchan_radindex = -1;
    dfs->dfs_extchan_radindex = -1;
    dfs->dfs_rinfo.rn_minrssithresh = min_rssithresh;
    /* Convert durations to TSF ticks */
    dfs->dfs_rinfo.rn_maxpulsedur = dfs_round((int32_t)((max_pulsedur*100/80)*100));
    /* relax the max pulse duration a little bit due to inaccuracy caused by chirping. */
    dfs->dfs_rinfo.rn_maxpulsedur = dfs->dfs_rinfo.rn_maxpulsedur +20;
    VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
                    "%s[%d]: DFS min filter rssiThresh = %d",
                    __func__, __LINE__, min_rssithresh);
    VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
                    "%s[%d]:DFS max pulse dur = %d ticks",
                    __func__ ,__LINE__, dfs->dfs_rinfo.rn_maxpulsedur);
    return DFS_STATUS_SUCCESS;

 bad4:
     return DFS_STATUS_FAIL;
}

void
dfs_clear_stats(struct ieee80211com *ic)
{
    struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs;
    if (dfs == NULL)
            return;
    OS_MEMZERO(&dfs->ath_dfs_stats, sizeof (struct dfs_stats));
    dfs->ath_dfs_stats.last_reset_tstamp = ic->ic_get_TSF64(ic);
}

#endif /* ATH_SUPPORT_DFS */
