/* Copyright (C) MOXA Inc. All rights reserved.

   This is free software distributed under the terms of the
   GNU Public License.  See the file COPYING-GPL for details.
*/

#ifndef MOXA_CAN_H
#define MOXA_CAN_H

#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/can.h>
#include <linux/can/dev.h>
#include <linux/can/error.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/atomic.h>

#include "can_linux_hal.h"
#include "can_linux_registers.h"
#include "can_lib.h"

struct moxa_can_priv {
	struct can_priv can;
	struct net_device *ndev;
	struct device *dev;
	
	//void __iomem *reg_base;
	volatile CAN_CTRL_t *ctrl;
	
	struct napi_struct napi;
	atomic_t handle_counter;

	uint8_t transmit_buffer;
    uint8_t stb_transmit_mode;
	uint8_t last_tec;
	uint8_t last_rec;

    /* Optional: Add any other private data needed */
	int channel; 
};

/* Core functions exported to bus drivers */
struct net_device *moxa_can_alloc(struct device *parent);
void moxa_can_free(struct net_device *ndev);
int moxa_can_register(struct net_device *ndev);
void moxa_can_unregister(struct net_device *ndev);
int moxa_can_suspend(struct net_device *ndev);
int moxa_can_resume(struct net_device *ndev);

/* Interrupt handler to be called from bus driver or registered by core if irq is passed */
irqreturn_t moxa_can_interrupt(int irq, void *dev_id);


#define START_AFWL 0x04 /**< receive buffer Almost Full Warning Limit */
#define START_EWL 0x0b /**< Programmable Error Warning Limit = (EWL+1)*8. */

#define CAN_CTRL_CLOCK 80000000u /**< CAN-CTRL running default with 80Mhz*/

/**
 * @brief stb configuration defines
 *
 */
enum stb_configuration_definition {
	STB_FIFO_MODE = 2, /**< secondary transmit buffer fifo mode value */
	STB_PRIO_MODE = 1, /**< secondary transmit buffer prio mode value */
	STB_TRANSMIT_NONE = 0, /**< secondary transmit buffer transmits Nothing */
	STB_TRANSMIT_ALL =
		2, /**< secondary transmit buffer Transmit ONE mode value */
	STB_TRANSMIT_ONE =
		1, /**< secondary transmit buffer Transmit ALL mode value */
};

/**
 * @brief stb configuration structure
 *
 */
struct stb_config {
	uint32_t transmit_mode;
	/* < secondary transmit buffer
	 * NOTHING = 0
	 * TSONE   = 1
	 * TSALL   = 2
	 */
	uint32_t scheduler_mode;
	/*< secondary transmit buffer
	 * NOTHING = 0
	 * PRIO    = 1
	 * FIFO    = 2
	 */
};

/**
 * @brief CAN transmit modes
 *
 */
enum transmit_modes {
	PTB_MODE = 0, /**< primary transmit buffer mode */
	STB_MODE = 1, /**< secondary transmit buffer mode */
};

/* compat wrapper */
#if defined(REDHAT_BASE)
/* RHEL9/Rocky9's headers：netif_napi_add() has 3 args */
#define MOXA_NETIF_NAPI_ADD(dev, napi, poll, weight) \
        netif_napi_add((dev), (napi), (poll))
#else
/* other distro/version: 4 args */
#define MOXA_NETIF_NAPI_ADD(dev, napi, poll, weight) \
        netif_napi_add((dev), (napi), (poll), (weight))
#endif


#endif /* MOXA_CAN_H */