/*
 * Copyright (c) 2012 Neratec Solutions AG
 *
 * 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.
 */

#include <linux/export.h>
#include <linux/slab.h>

#include "ath.h"
#include "dfs_pattern_detector.h"
#include "dfs_pri_detector.h"

/**
 * struct radar_types - contains array of patterns defined for one DFS domain
 * @domain: DFS regulatory domain
 * @num_radar_types: number of radar types to follow
 * @radar_types: radar types array
 */
struct radar_types {
    enum nl80211_dfs_regions region;
    uint32_t num_radar_types;
    const struct radar_detector_specs* radar_types;
};

/* percentage on ppb threshold to trigger detection */
#define MIN_PPB_THRESH 50
#define PPB_THRESH_RATE(PPB, RATE) ((PPB * RATE + 100 - RATE) / 100)
#define PPB_THRESH(PPB) PPB_THRESH_RATE(PPB, MIN_PPB_THRESH)
#define PRF2PRI(PRF) ((1000000 + PRF / 2) / PRF)
/* percentage of pulse width tolerance */
#define WIDTH_TOLERANCE 5
#define WIDTH_LOWER(X) ((X * (100 - WIDTH_TOLERANCE) + 50) / 100)
#define WIDTH_UPPER(X) ((X * (100 + WIDTH_TOLERANCE) + 50) / 100)

#define ETSI_PATTERN(ID, WMIN, WMAX, PMIN, PMAX, PRF, PPB, CHIRP)                                 \
    {                                                                                             \
        ID, WIDTH_LOWER(WMIN), WIDTH_UPPER(WMAX), (PRF2PRI(PMAX) - PRI_TOLERANCE),                \
            (PRF2PRI(PMIN) * PRF + PRI_TOLERANCE), PRF, PPB *PRF, PPB_THRESH(PPB), PRI_TOLERANCE, \
            CHIRP                                                                                 \
    }

/* radar types as defined by ETSI EN-301-893 v1.5.1 */
static const struct radar_detector_specs etsi_radar_ref_types_v15[] = {
    // clang-format off
    ETSI_PATTERN(0,  0,  1,  700,  700, 1, 18, false),
    ETSI_PATTERN(1,  0,  5,  200, 1000, 1, 10, false),
    ETSI_PATTERN(2,  0, 15,  200, 1600, 1, 15, false),
    ETSI_PATTERN(3,  0, 15, 2300, 4000, 1, 25, false),
    ETSI_PATTERN(4, 20, 30, 2000, 4000, 1, 20, false),
    ETSI_PATTERN(5,  0,  2,  300,  400, 3, 10, false),
    ETSI_PATTERN(6,  0,  2,  400, 1200, 3, 15, false),
    // clang-format on
};

static const struct radar_types etsi_radar_types_v15 = {
    // clang-format off
    .region             = NL80211_DFS_ETSI,
    .num_radar_types    = ARRAY_SIZE(etsi_radar_ref_types_v15),
    .radar_types        = etsi_radar_ref_types_v15,
    // clang-format on
};

#define FCC_PATTERN(ID, WMIN, WMAX, PMIN, PMAX, PRF, PPB, CHIRP)                                   \
    {                                                                                              \
        ID, WIDTH_LOWER(WMIN), WIDTH_UPPER(WMAX), PMIN - PRI_TOLERANCE, PMAX *PRF + PRI_TOLERANCE, \
            PRF, PPB *PRF, PPB_THRESH(PPB), PRI_TOLERANCE, CHIRP                                   \
    }

/* radar types released on August 14, 2014
 * type 1 PRI values randomly selected within the range of 518 and 3066.
 * divide it to 3 groups is good enough for both of radar detection and
 * avoiding false detection based on practical test results
 * collected for more than a year.
 */
static const struct radar_detector_specs fcc_radar_ref_types[] = {
    // clang-format off
    FCC_PATTERN(  0,  0,   1, 1428, 1428, 1, 18, false),
    FCC_PATTERN(101,  0,   1,  518,  938, 1, 57, false),
    FCC_PATTERN(102,  0,   1,  938, 2000, 1, 27, false),
    FCC_PATTERN(103,  0,   1, 2000, 3066, 1, 18, false),
    FCC_PATTERN(  2,  0,   5,  150,  230, 1, 23, false),
    FCC_PATTERN(  3,  6,  10,  200,  500, 1, 16, false),
    FCC_PATTERN(  4, 11,  20,  200,  500, 1, 12, false),
    FCC_PATTERN(  5, 50, 100, 1000, 2000, 1,  1, true),
    FCC_PATTERN(  6,  0,   1,  333,  333, 1,  9, false),
    // clang-format on
};

static const struct radar_types fcc_radar_types = {
    // clang-format off
    .region             = NL80211_DFS_FCC,
    .num_radar_types    = ARRAY_SIZE(fcc_radar_ref_types),
    .radar_types        = fcc_radar_ref_types,
    // clang-format on
};

#define JP_PATTERN(ID, WMIN, WMAX, PMIN, PMAX, PRF, PPB, RATE, CHIRP)                              \
    {                                                                                              \
        ID, WIDTH_LOWER(WMIN), WIDTH_UPPER(WMAX), PMIN - PRI_TOLERANCE, PMAX *PRF + PRI_TOLERANCE, \
            PRF, PPB *PRF, PPB_THRESH_RATE(PPB, RATE), PRI_TOLERANCE, CHIRP                        \
    }
static const struct radar_detector_specs jp_radar_ref_types[] = {
    // clang-format off
    JP_PATTERN(0,  0,   1, 1428, 1428, 1, 18, 29, false),
    JP_PATTERN(1,  2,   3, 3846, 3846, 1, 18, 29, false),
    JP_PATTERN(2,  0,   1, 1388, 1388, 1, 18, 50, false),
    JP_PATTERN(3,  1,   2, 4000, 4000, 1, 18, 50, false),
    JP_PATTERN(4,  0,   5,  150,  230, 1, 23, 50, false),
    JP_PATTERN(5,  6,  10,  200,  500, 1, 16, 50, false),
    JP_PATTERN(6, 11,  20,  200,  500, 1, 12, 50, false),
    JP_PATTERN(7, 50, 100, 1000, 2000, 1,  3, 50, false),
    JP_PATTERN(5,  0,   1,  333,  333, 1,  9, 50, false),
    // clang-format on
};

static const struct radar_types jp_radar_types = {
    // clang-format off
    .region             = NL80211_DFS_JP,
    .num_radar_types    = ARRAY_SIZE(jp_radar_ref_types),
    .radar_types        = jp_radar_ref_types,
    // clang-format on
};

static const struct radar_types* dfs_domains[] = {
    &etsi_radar_types_v15,
    &fcc_radar_types,
    &jp_radar_types,
};

/**
 * get_dfs_domain_radar_types() - get radar types for a given DFS domain
 * @param domain DFS domain
 * @return radar_types ptr on success, NULL if DFS domain is not supported
 */
static const struct radar_types* get_dfs_domain_radar_types(enum nl80211_dfs_regions region) {
    uint32_t i;
    for (i = 0; i < ARRAY_SIZE(dfs_domains); i++) {
        if (dfs_domains[i]->region == region) { return dfs_domains[i]; }
    }
    return NULL;
}

/**
 * struct channel_detector - detector elements for a DFS channel
 * @head: list_head
 * @freq: frequency for this channel detector in MHz
 * @detectors: array of dynamically created detector elements for this freq
 *
 * Channel detectors are required to provide multi-channel DFS detection, e.g.
 * to support off-channel scanning. A pattern detector has a list of channels
 * radar pulses have been reported for in the past.
 */
struct channel_detector {
    struct list_head head;
    uint16_t freq;
    struct pri_detector** detectors;
};

/* channel_detector_reset() - reset detector lines for a given channel */
static void channel_detector_reset(struct dfs_pattern_detector* dpd, struct channel_detector* cd) {
    uint32_t i;
    if (cd == NULL) { return; }
    for (i = 0; i < dpd->num_radar_types; i++) {
        cd->detectors[i]->reset(cd->detectors[i], dpd->last_pulse_ts);
    }
}

/* channel_detector_exit() - destructor */
static void channel_detector_exit(struct dfs_pattern_detector* dpd, struct channel_detector* cd) {
    uint32_t i;
    if (cd == NULL) { return; }
    list_del(&cd->head);
    for (i = 0; i < dpd->num_radar_types; i++) {
        struct pri_detector* de = cd->detectors[i];
        if (de != NULL) { de->exit(de); }
    }
    kfree(cd->detectors);
    kfree(cd);
}

static struct channel_detector* channel_detector_create(struct dfs_pattern_detector* dpd,
                                                        uint16_t freq) {
    uint32_t sz, i;
    struct channel_detector* cd;

    cd = kmalloc(sizeof(*cd), GFP_ATOMIC);
    if (cd == NULL) { goto fail; }

    INIT_LIST_HEAD(&cd->head);
    cd->freq = freq;
    sz = sizeof(cd->detectors) * dpd->num_radar_types;
    cd->detectors = kzalloc(sz, GFP_ATOMIC);
    if (cd->detectors == NULL) { goto fail; }

    for (i = 0; i < dpd->num_radar_types; i++) {
        const struct radar_detector_specs* rs = &dpd->radar_spec[i];
        struct pri_detector* de = pri_detector_init(rs);
        if (de == NULL) { goto fail; }
        cd->detectors[i] = de;
    }
    list_add(&cd->head, &dpd->channel_detectors);
    return cd;

fail:
    ath_dbg(dpd->common, DFS, "failed to allocate channel_detector for freq=%d\n", freq);
    channel_detector_exit(dpd, cd);
    return NULL;
}

/**
 * channel_detector_get() - get channel detector for given frequency
 * @param dpd instance pointer
 * @param freq frequency in MHz
 * @return pointer to channel detector on success, NULL otherwise
 *
 * Return existing channel detector for the given frequency or return a
 * newly create one.
 */
static struct channel_detector* channel_detector_get(struct dfs_pattern_detector* dpd,
                                                     uint16_t freq) {
    struct channel_detector* cd;
    list_for_each_entry(cd, &dpd->channel_detectors, head) {
        if (cd->freq == freq) { return cd; }
    }
    return channel_detector_create(dpd, freq);
}

/*
 * DFS Pattern Detector
 */

/* dpd_reset(): reset all channel detectors */
static void dpd_reset(struct dfs_pattern_detector* dpd) {
    struct channel_detector* cd;
    if (!list_empty(&dpd->channel_detectors))
        list_for_each_entry(cd, &dpd->channel_detectors, head) channel_detector_reset(dpd, cd);
}
static void dpd_exit(struct dfs_pattern_detector* dpd) {
    struct channel_detector *cd, *cd0;
    if (!list_empty(&dpd->channel_detectors))
        list_for_each_entry_safe(cd, cd0, &dpd->channel_detectors, head)
            channel_detector_exit(dpd, cd);
    kfree(dpd);
}

static bool dpd_add_pulse(struct dfs_pattern_detector* dpd, struct pulse_event* event) {
    uint32_t i;
    struct channel_detector* cd;

    /*
     * pulses received for a non-supported or un-initialized
     * domain are treated as detected radars for fail-safety
     */
    if (dpd->region == NL80211_DFS_UNSET) { return true; }

    cd = channel_detector_get(dpd, event->freq);
    if (cd == NULL) { return false; }

    /* reset detector on time stamp wraparound, caused by TSF reset */
    if (event->ts < dpd->last_pulse_ts) { dpd_reset(dpd); }
    dpd->last_pulse_ts = event->ts;

    /* do type individual pattern matching */
    for (i = 0; i < dpd->num_radar_types; i++) {
        struct pri_detector* pd = cd->detectors[i];
        struct pri_sequence* ps = pd->add_pulse(pd, event);
        if (ps != NULL) {
            ath_dbg(dpd->common, DFS,
                    "DFS: radar found on freq=%d: id=%d, pri=%d, "
                    "count=%d, count_false=%d\n",
                    event->freq, pd->rs->type_id, ps->pri, ps->count, ps->count_falses);
            pd->reset(pd, dpd->last_pulse_ts);
            return true;
        }
    }
    return false;
}

static struct ath_dfs_pool_stats dpd_get_stats(struct dfs_pattern_detector* dpd) {
    return global_dfs_pool_stats;
}

static bool dpd_set_domain(struct dfs_pattern_detector* dpd, enum nl80211_dfs_regions region) {
    const struct radar_types* rt;
    struct channel_detector *cd, *cd0;

    if (dpd->region == region) { return true; }

    dpd->region = NL80211_DFS_UNSET;

    rt = get_dfs_domain_radar_types(region);
    if (rt == NULL) { return false; }

    /* delete all channel detectors for previous DFS domain */
    if (!list_empty(&dpd->channel_detectors))
        list_for_each_entry_safe(cd, cd0, &dpd->channel_detectors, head)
            channel_detector_exit(dpd, cd);
    dpd->radar_spec = rt->radar_types;
    dpd->num_radar_types = rt->num_radar_types;

    dpd->region = region;
    return true;
}

static const struct dfs_pattern_detector default_dpd = {
    .exit = dpd_exit,
    .set_dfs_domain = dpd_set_domain,
    .add_pulse = dpd_add_pulse,
    .get_stats = dpd_get_stats,
    .region = NL80211_DFS_UNSET,
};

struct dfs_pattern_detector* dfs_pattern_detector_init(struct ath_common* common,
                                                       enum nl80211_dfs_regions region) {
    struct dfs_pattern_detector* dpd;

    if (!IS_ENABLED(CONFIG_CFG80211_CERTIFICATION_ONUS)) { return NULL; }

    dpd = kmalloc(sizeof(*dpd), GFP_KERNEL);
    if (dpd == NULL) { return NULL; }

    *dpd = default_dpd;
    INIT_LIST_HEAD(&dpd->channel_detectors);

    dpd->common = common;
    if (dpd->set_dfs_domain(dpd, region)) { return dpd; }

    ath_dbg(common, DFS, "Could not set DFS domain to %d", region);
    kfree(dpd);
    return NULL;
}
EXPORT_SYMBOL(dfs_pattern_detector_init);
