/*
 * Copyright (c) 2018 The Fuchsia Authors
 *
 * 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 "device.h"

#include <stdatomic.h>

#include "debug.h"

pthread_mutex_t irq_callback_lock;

async_dispatcher_t* default_dispatcher;

static void brcmf_timer_handler(async_dispatcher_t* dispatcher, async_task_t* task,
                                zx_status_t status) {
    if (status != ZX_OK) {
        return;
    }
    brcmf_timer_info_t* timer = containerof(task, brcmf_timer_info_t, task);
    timer->callback_function(timer->data);
    mtx_lock(&timer->lock);
    timer->scheduled = false;
    sync_completion_signal(&timer->finished);
    mtx_unlock(&timer->lock);
}

void brcmf_timer_init(brcmf_timer_info_t* timer, brcmf_timer_callback_t* callback, void* data) {
    memset(&timer->task.state, 0, sizeof(timer->task.state));
    timer->task.handler = brcmf_timer_handler;
    timer->data = data;
    timer->callback_function = callback;
    timer->finished = SYNC_COMPLETION_INIT;
    timer->scheduled = false;
    mtx_init(&timer->lock, mtx_plain);
}

void brcmf_timer_set(brcmf_timer_info_t* timer, zx_duration_t delay) {
    mtx_lock(&timer->lock);
    async_cancel_task(default_dispatcher, &timer->task); // Make sure it's not scheduled
    timer->task.deadline = delay + async_now(default_dispatcher);
    timer->scheduled = true;
    sync_completion_reset(&timer->finished);
    async_post_task(default_dispatcher, &timer->task);
    mtx_unlock(&timer->lock);
}

void brcmf_timer_stop(brcmf_timer_info_t* timer) {
    mtx_lock(&timer->lock);
    if (!timer->scheduled) {
        mtx_unlock(&timer->lock);
        return;
    }
    zx_status_t result = async_cancel_task(default_dispatcher, &timer->task);
    mtx_unlock(&timer->lock);
    if (result != ZX_OK) {
        sync_completion_wait(&timer->finished, ZX_TIME_INFINITE);
    }
}

struct net_device* brcmf_allocate_net_device(size_t priv_size, const char* name) {
    struct net_device* dev = calloc(1, sizeof(*dev));
    if (dev == NULL) {
        return NULL;
    }
    dev->priv = calloc(1, priv_size);
    if (dev->priv == NULL) {
        free(dev);
        return NULL;
    }
    strlcpy(dev->name, name, sizeof(dev->name));
    return dev;
}

void brcmf_free_net_device(struct net_device* dev) {
    if (dev != NULL) {
        free(dev->priv);
    }
    free(dev);
}

void brcmf_enable_tx(struct net_device* dev) {
    brcmf_dbg(INFO, " * * NOTE: brcmf_enable_tx called. Enable TX. (Was netif_wake_queue)");
}

// This is a kill-flies-with-sledgehammers, just-get-it-working version; TODO(NET-805) for
// efficiency.

bool brcmf_test_and_set_bit_in_array(size_t bit_number, atomic_ulong* addr) {
    size_t index = bit_number >> 6;
    uint64_t bit = 1 << (bit_number & 0x3f);
    return !!(atomic_fetch_or(&addr[index], bit) & bit);
}

bool brcmf_test_and_clear_bit_in_array(size_t bit_number, atomic_ulong* addr) {
    uint32_t index = bit_number >> 6;
    uint64_t bit = 1 << (bit_number & 0x3f);
    return !!(atomic_fetch_and(&addr[index], ~bit) & bit);
}

bool brcmf_test_bit_in_array(size_t bit_number, atomic_ulong* addr) {
    uint32_t index = bit_number >> 6;
    uint64_t bit = 1 << (bit_number & 0x3f);
    return !!(atomic_load(&addr[index]) & bit);
}

void brcmf_clear_bit_in_array(size_t bit_number, atomic_ulong* addr) {
    (void)brcmf_test_and_clear_bit_in_array(bit_number, addr);
}

void brcmf_set_bit_in_array(size_t bit_number, atomic_ulong* addr) {
    (void)brcmf_test_and_set_bit_in_array(bit_number, addr);
}

// TODO(jeffbrown): Once we have an equivalent of debugfs, implement / connect these.
zx_status_t brcmf_debugfs_create_directory(const char *name, zx_handle_t parent,
                                           zx_handle_t* new_directory_out) {
    if (new_directory_out) {
        *new_directory_out = ZX_HANDLE_INVALID;
    }
    return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t brcmf_debugfs_create_sequential_file(void* dev, const char* fn, zx_handle_t parent,
                                                 zx_status_t (*read_fn)(struct seq_file* seq,
                                                                        void* data),
                                                 zx_handle_t* new_file_out) {
    if (new_file_out) {
        *new_file_out = ZX_HANDLE_INVALID;
    }
    return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t brcmf_debugfs_rm_recursive(zx_handle_t dir) {
    return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t brcmf_debugfs_create_u32_file(const char* name, uint32_t permissions,
                                          zx_handle_t parent, uint32_t* data_to_access) {
    return ZX_ERR_NOT_SUPPORTED;
}
