/*
 * Copyright (c) 2011-2014, 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.
 */

/*=== includes ===*/
/* header files for OS primitives */
#include <osdep.h>        /* u_int32_t, etc. */
#include <adf_os_mem.h>   /* adf_os_mem_alloc, etc. */
#include <adf_os_types.h> /* adf_os_device_t, adf_os_print */
/* header files for utilities */
#include <queue.h>        /* TAILQ */

/* header files for configuration API */
#include <ol_cfg.h>       /* ol_cfg_max_peer_id */

/* header files for our internal definitions */
#include <ol_txrx_api.h>       /* ol_txrx_pdev_t, etc. */
#include <ol_txrx_dbg.h>       /* TXRX_DEBUG_LEVEL */
#include <ol_txrx_internal.h>  /* ol_txrx_pdev_t, etc. */
#include <ol_txrx.h>           /* ol_txrx_peer_unref_delete */
#include <ol_txrx_peer_find.h> /* ol_txrx_peer_find_attach, etc. */
#include <ol_tx_queue.h>

/*=== misc. / utility function definitions ==================================*/

static int
ol_txrx_log2_ceil(unsigned value)
{
    /* need to switch to unsigned math so that negative values
     * will right-shift towards 0 instead of -1
     */
    unsigned tmp = value;
    int log2 = -1;

    if (value == 0)
    {
        TXRX_ASSERT2(0);
        return 0;
    }

    while (tmp) {
        log2++;
        tmp >>= 1;
    }
    if (1U << log2 != value) {
        log2++;
    }

    return log2;
}

static int
ol_txrx_peer_find_add_id_to_obj(
    struct ol_txrx_peer_t *peer,
    u_int16_t peer_id)
{
    int i;

    for (i = 0; i < MAX_NUM_PEER_ID_PER_PEER; i++) {
        if (peer->peer_ids[i] == HTT_INVALID_PEER) {
            peer->peer_ids[i] = peer_id;
            return 0; /* success */
        }
    }
    return 1; /* failure */
}

/*=== function definitions for peer MAC addr --> peer object hash table =====*/

/*
 * TXRX_PEER_HASH_LOAD_FACTOR:
 * Multiply by 2 and divide by 2^0 (shift by 0), then round up to a
 * power of two.
 * This provides at least twice as many bins in the peer hash table
 * as there will be entries.
 * Having substantially more bins than spaces minimizes the probability of
 * having to compare MAC addresses.
 * Because the MAC address comparison is fairly efficient, it is okay if the
 * hash table is sparsely loaded, but it's generally better to use extra mem
 * to keep the table sparse, to keep the lookups as fast as possible.
 * An optimization would be to apply a more conservative loading factor for
 * high latency, where the lookup happens during the tx classification of
 * every tx frame, than for low-latency, where the lookup only happens
 * during association, when the PEER_MAP message is received.
 */
#define TXRX_PEER_HASH_LOAD_MULT  2
#define TXRX_PEER_HASH_LOAD_SHIFT 0

static int
ol_txrx_peer_find_hash_attach(struct ol_txrx_pdev_t *pdev)
{
    int i, hash_elems, log2;

    /* allocate the peer MAC address -> peer object hash table */
    hash_elems = ol_cfg_max_peer_id(pdev->ctrl_pdev) + 1;
    hash_elems *= TXRX_PEER_HASH_LOAD_MULT;
    hash_elems >>= TXRX_PEER_HASH_LOAD_SHIFT;
    log2 = ol_txrx_log2_ceil(hash_elems);
    hash_elems = 1 << log2;

    pdev->peer_hash.mask = hash_elems - 1;
    pdev->peer_hash.idx_bits = log2;
    /* allocate an array of TAILQ peer object lists */
    pdev->peer_hash.bins = adf_os_mem_alloc(
        pdev->osdev,
        hash_elems * sizeof(TAILQ_HEAD(anonymous_tail_q, ol_txrx_peer_t)));
    if (!pdev->peer_hash.bins) {
        return 1; /* failure */
    }
    for (i = 0; i < hash_elems; i++) {
        TAILQ_INIT(&pdev->peer_hash.bins[i]);
    }
    return 0; /* success */
}

static void
ol_txrx_peer_find_hash_detach(struct ol_txrx_pdev_t *pdev)
{
    adf_os_mem_free(pdev->peer_hash.bins);
}

static inline unsigned
ol_txrx_peer_find_hash_index(
    struct ol_txrx_pdev_t *pdev,
    union ol_txrx_align_mac_addr_t *mac_addr)
{
    unsigned index;

    index =
        mac_addr->align2.bytes_ab ^
        mac_addr->align2.bytes_cd ^
        mac_addr->align2.bytes_ef;
    index ^= index >> pdev->peer_hash.idx_bits;
    index &= pdev->peer_hash.mask;
    return index;
}


void
ol_txrx_peer_find_hash_add(
    struct ol_txrx_pdev_t *pdev,
    struct ol_txrx_peer_t *peer)
{
    unsigned index;

    index = ol_txrx_peer_find_hash_index(pdev, &peer->mac_addr);
    adf_os_spin_lock_bh(&pdev->peer_ref_mutex);
    /*
     * It is important to add the new peer at the tail of the peer list
     * with the bin index.  Together with having the hash_find function
     * search from head to tail, this ensures that if two entries with
     * the same MAC address are stored, the one added first will be
     * found first.
     */
    TAILQ_INSERT_TAIL(&pdev->peer_hash.bins[index], peer, hash_list_elem);
    adf_os_spin_unlock_bh(&pdev->peer_ref_mutex);
}

struct ol_txrx_peer_t *
ol_txrx_peer_vdev_find_hash(struct ol_txrx_pdev_t *pdev,
                            struct ol_txrx_vdev_t *vdev,
                            u_int8_t *peer_mac_addr,
                            int mac_addr_is_aligned,
                            u_int8_t check_valid)
{
    union ol_txrx_align_mac_addr_t local_mac_addr_aligned, *mac_addr;
    unsigned index;
    struct ol_txrx_peer_t *peer;

    if (mac_addr_is_aligned) {
        mac_addr = (union ol_txrx_align_mac_addr_t *) peer_mac_addr;
    } else {
        adf_os_mem_copy(
            &local_mac_addr_aligned.raw[0],
            peer_mac_addr, OL_TXRX_MAC_ADDR_LEN);
        mac_addr = &local_mac_addr_aligned;
    }
    index = ol_txrx_peer_find_hash_index(pdev, mac_addr);
    adf_os_spin_lock_bh(&pdev->peer_ref_mutex);
    TAILQ_FOREACH(peer, &pdev->peer_hash.bins[index], hash_list_elem) {
        if (ol_txrx_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0
            && (check_valid == 0 || peer->valid) && peer->vdev == vdev )  {
            /* found it - increment the ref count before releasing the lock */
            adf_os_atomic_inc(&peer->ref_cnt);
            adf_os_spin_unlock_bh(&pdev->peer_ref_mutex);
            return peer;
        }
    }
    adf_os_spin_unlock_bh(&pdev->peer_ref_mutex);
    return NULL; /* failure */
}

struct ol_txrx_peer_t *
ol_txrx_peer_find_hash_find(
    struct ol_txrx_pdev_t *pdev,
    u_int8_t *peer_mac_addr,
    int mac_addr_is_aligned,
    u_int8_t check_valid)
{
    union ol_txrx_align_mac_addr_t local_mac_addr_aligned, *mac_addr;
    unsigned index;
    struct ol_txrx_peer_t *peer;

    if (mac_addr_is_aligned) {
        mac_addr = (union ol_txrx_align_mac_addr_t *) peer_mac_addr;
    } else {
        adf_os_mem_copy(
            &local_mac_addr_aligned.raw[0],
            peer_mac_addr, OL_TXRX_MAC_ADDR_LEN);
        mac_addr = &local_mac_addr_aligned;
    }
    index = ol_txrx_peer_find_hash_index(pdev, mac_addr);
    adf_os_spin_lock_bh(&pdev->peer_ref_mutex);
    TAILQ_FOREACH(peer, &pdev->peer_hash.bins[index], hash_list_elem) {
        if (ol_txrx_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0
            && (check_valid == 0 || peer->valid)) {
            /* found it - increment the ref count before releasing the lock */
            adf_os_atomic_inc(&peer->ref_cnt);
            adf_os_spin_unlock_bh(&pdev->peer_ref_mutex);
            return peer;
        }
    }
    adf_os_spin_unlock_bh(&pdev->peer_ref_mutex);
    return NULL; /* failure */
}

void
ol_txrx_peer_find_hash_remove(
    struct ol_txrx_pdev_t *pdev,
    struct ol_txrx_peer_t *peer)
{
    unsigned index;

    index = ol_txrx_peer_find_hash_index(pdev, &peer->mac_addr);
    /*
     * DO NOT take the peer_ref_mutex lock here - it needs to be taken
     * by the caller.
     * The caller needs to hold the lock from the time the peer object's
     * reference count is decremented and tested up through the time the
     * reference to the peer object is removed from the hash table, by
     * this function.
     * Holding the lock only while removing the peer object reference
     * from the hash table keeps the hash table consistent, but does not
     * protect against a new HL tx context starting to use the peer object
     * if it looks up the peer object from its MAC address just after the
     * peer ref count is decremented to zero, but just before the peer
     * object reference is removed from the hash table.
     */
    //adf_os_spin_lock_bh(&pdev->peer_ref_mutex);
    TAILQ_REMOVE(&pdev->peer_hash.bins[index], peer, hash_list_elem);
    //adf_os_spin_unlock_bh(&pdev->peer_ref_mutex);
}

void
ol_txrx_peer_find_hash_erase(struct ol_txrx_pdev_t *pdev)
{
    unsigned i;
    /*
     * Not really necessary to take peer_ref_mutex lock - by this point,
     * it's known that the pdev is no longer in use.
     */

    for (i = 0; i <= pdev->peer_hash.mask; i++) {
        if (!TAILQ_EMPTY(&pdev->peer_hash.bins[i])) {
            struct ol_txrx_peer_t *peer, *peer_next;

			/*
			 * TAILQ_FOREACH_SAFE must be used here to avoid any memory access
			 * violation after peer is freed
			 */
			TAILQ_FOREACH_SAFE(
                peer, &pdev->peer_hash.bins[i], hash_list_elem, peer_next)
			{
				/*
                 * Don't remove the peer from the hash table -
                 * that would modify the list we are currently traversing,
                 * and it's not necessary anyway.
                 */
                /*
                 * Artificially adjust the peer's ref count to 1, so it
                 * will get deleted by ol_txrx_peer_unref_delete.
                 */
                adf_os_atomic_init(&peer->ref_cnt); /* set to zero */
                adf_os_atomic_inc(&peer->ref_cnt);  /* incr to one */
                TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "%s: Delete Peer %pK\n", __func__, peer);
                ol_txrx_peer_unref_delete(peer);
            }
        }
    }
}

/*=== function definitions for peer id --> peer object map ==================*/

static int
ol_txrx_peer_find_map_attach(struct ol_txrx_pdev_t *pdev)
{
    int max_peers, peer_map_size;

    /* allocate the peer ID -> peer object map */
    max_peers = ol_cfg_max_peer_id(pdev->ctrl_pdev) + 1;
    peer_map_size = max_peers * sizeof(pdev->peer_id_to_obj_map[0]);
    pdev->peer_id_to_obj_map = adf_os_mem_alloc(pdev->osdev, peer_map_size);
    if (!pdev->peer_id_to_obj_map) {
        return 1; /* failure */
    }

    /*
     * The peer_id_to_obj_map doesn't really need to be initialized,
     * since elements are only used after they have been individually
     * initialized.
     * However, it is convenient for debugging to have all elements
     * that are not in use set to 0.
     */
    adf_os_mem_set(pdev->peer_id_to_obj_map, 0, peer_map_size);

    return 0; /* success */
}

static void
ol_txrx_peer_find_map_detach(struct ol_txrx_pdev_t *pdev)
{
    adf_os_mem_free(pdev->peer_id_to_obj_map);
}

static inline void
ol_txrx_peer_find_add_id(
    struct ol_txrx_pdev_t *pdev,
    u_int8_t *peer_mac_addr,
    u_int16_t peer_id)
{
    struct ol_txrx_peer_t *peer;

    /* check if there's already a peer object with this MAC address */
    peer = ol_txrx_peer_find_hash_find(pdev, peer_mac_addr, 1 /* is aligned */, 0);
    TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1,
        "%s: peer %pK ID %d\n", __func__, peer, peer_id);
    if (peer) {
        /* peer's ref count was already incremented by peer_find_hash_find */
        pdev->peer_id_to_obj_map[peer_id] = peer;
        /*
         * remove the reference added in ol_txrx_peer_find_hash_find.
         * the reference for the first peer id is already added in ol_txrx_peer_attach.
         * Riva/Pronto has one peer id for each peer.
         * Peregrine/Rome has two peer id for each peer.
         */
        if (peer->peer_ids[0] == HTT_INVALID_PEER) {
            ol_txrx_peer_unref_delete(peer);
        }
        if (ol_txrx_peer_find_add_id_to_obj(peer, peer_id)) {
            /* TBDXXX: assert for now */
            adf_os_assert(0);
        }
        return;
    }
    /*
     * Currently peer IDs are assigned for vdevs as well as peers.
     * If the peer ID is for a vdev, then we will fail to find a peer
     * with a matching MAC address.
     */
    //TXRX_ASSERT2(0);
}

/*=== allocation / deallocation function definitions ========================*/

int
ol_txrx_peer_find_attach(struct ol_txrx_pdev_t *pdev)
{
    if (ol_txrx_peer_find_map_attach(pdev)) {
        return 1;
    }
    if (ol_txrx_peer_find_hash_attach(pdev)) {
        ol_txrx_peer_find_map_detach(pdev);
        return 1;
    }
    return 0; /* success */
}

void
ol_txrx_peer_find_detach(struct ol_txrx_pdev_t *pdev)
{
    ol_txrx_peer_find_map_detach(pdev);
    ol_txrx_peer_find_hash_detach(pdev);
}

/*=== function definitions for message handling =============================*/

void
ol_rx_peer_map_handler(
    ol_txrx_pdev_handle pdev,
    u_int16_t peer_id,
    u_int8_t vdev_id,
    u_int8_t *peer_mac_addr,
    int tx_ready)
{
    ol_txrx_peer_find_add_id(pdev, peer_mac_addr, peer_id);
    if (pdev->cfg.is_high_latency && !tx_ready) {
        struct ol_txrx_peer_t *peer;
        peer = ol_txrx_peer_find_by_id(pdev, peer_id);
        if (!peer) {
            /* ol_txrx_peer_detach called before peer map arrived */
            return;
        }else {
            if (tx_ready) {
#if defined(CONFIG_HL_SUPPORT)
                int i;
                /* unpause all tx queues now, since the target is ready */
                for (i = 0; i < ARRAY_LEN(peer->txqs); i++) {
                    ol_txrx_peer_tid_unpause(peer, i);
                }
#endif
            } else {
                /* walk through paused mgmt queue, update tx descriptors */
                ol_tx_queue_decs_reinit(peer, peer_id);

                /* keep non-mgmt tx queues paused until assoc is finished */
                /* tx queues were paused in ol_txrx_peer_attach*/
                /* unpause tx mgmt queue */
                ol_txrx_peer_tid_unpause(peer, HTT_TX_EXT_TID_MGMT);
            }
        }
    }
}

void
ol_txrx_peer_tx_ready_handler(ol_txrx_pdev_handle pdev, u_int16_t peer_id)
{
#if defined(CONFIG_HL_SUPPORT)
    struct ol_txrx_peer_t *peer;
    peer = ol_txrx_peer_find_by_id(pdev, peer_id);
    if (peer) {
        int i;
        /*
         * Unpause all data tx queues now that the target is ready.
         * The mgmt tx queue was not paused, so skip it.
         */
        for (i = 0; i < ARRAY_LEN(peer->txqs); i++) {
            if (i == HTT_TX_EXT_TID_MGMT) {
                continue; /* mgmt tx queue was not paused */
            }
            ol_txrx_peer_tid_unpause(peer, i);
        }
    }
#endif
}

void
ol_rx_peer_unmap_handler(
    ol_txrx_pdev_handle pdev,
    u_int16_t peer_id)
{
    struct ol_txrx_peer_t *peer;
    peer = (peer_id == HTT_INVALID_PEER) ? NULL :
        pdev->peer_id_to_obj_map[peer_id];
    TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1,
        "%s: peer %pK with ID %d to be unmapped.\n", __func__, peer, peer_id);
    pdev->peer_id_to_obj_map[peer_id] = NULL;
    /*
     * Currently peer IDs are assigned for vdevs as well as peers.
     * If the peer ID is for a vdev, then the peer pointer stored
     * in peer_id_to_obj_map will be NULL.
     */
    if (!peer) return;
    /*
     * Remove a reference to the peer.
     * If there are no more references, delete the peer object.
     */
    TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1,
        "%s: Remove the ID %d reference to peer %pK\n",
        __func__, peer_id, peer);
    ol_txrx_peer_unref_delete(peer);
}

struct ol_txrx_peer_t *
ol_txrx_assoc_peer_find(struct ol_txrx_vdev_t *vdev)
{
	struct ol_txrx_peer_t *peer;

	adf_os_spin_lock_bh(&vdev->pdev->last_real_peer_mutex);
	/*
	 * Check the TXRX Peer is itself valid And also
	 * if HTT Peer ID has been setup for this peer
	 */
	if (vdev->last_real_peer && vdev->last_real_peer->peer_ids[0] != HTT_INVALID_PEER_ID)
	{
		adf_os_atomic_inc(&vdev->last_real_peer->ref_cnt);
		peer = vdev->last_real_peer;
	} else {
		peer = NULL;
	}
	adf_os_spin_unlock_bh(&vdev->pdev->last_real_peer_mutex);
	return peer;
}

/*=== function definitions for debug ========================================*/

#if defined (TXRX_DEBUG_LEVEL) && TXRX_DEBUG_LEVEL > 5
void
ol_txrx_peer_find_display(ol_txrx_pdev_handle pdev, int indent)
{
    int i, max_peers;

    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW,
        "%*speer map:\n", indent, " ");
    max_peers = ol_cfg_max_peer_id(pdev->ctrl_pdev) + 1;
    for (i = 0; i < max_peers; i++) {
        if (pdev->peer_id_to_obj_map[i]) {
            VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW,
                "%*sid %d -> %pK\n",
                indent+4, " ", i, pdev->peer_id_to_obj_map[i]);
        }
    }
    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW,
        "%*speer hash table:\n", indent, " ");
    for (i = 0; i <= pdev->peer_hash.mask; i++) {
        if (!TAILQ_EMPTY(&pdev->peer_hash.bins[i])) {
            struct ol_txrx_peer_t *peer;
            TAILQ_FOREACH(peer, &pdev->peer_hash.bins[i], hash_list_elem) {
                VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW,
                    "%*shash idx %d -> %pK (%02x:%02x:%02x:%02x:%02x:%02x)\n",
                    indent+4, " ", i, peer,
                    peer->mac_addr.raw[0], peer->mac_addr.raw[1],
                    peer->mac_addr.raw[2], peer->mac_addr.raw[3],
                    peer->mac_addr.raw[4], peer->mac_addr.raw[5]);
            }
        }
    }
}
#endif /* if TXRX_DEBUG_LEVEL */
