/* SPDX-License-Identifier: GPL-2.0-only */


#ifndef _IPA_ETH_H_
#define _IPA_ETH_H_

#include <linux/ipa.h>
#include <linux/msm_ipa.h>
#include <linux/msm_gsi.h>

#define IPA_ETH_API_VER 2



typedef void (*ipa_eth_ready_cb)(void *user_data);
typedef u32 ipa_eth_hdl_t;


struct ipa_eth_ready {
	ipa_eth_ready_cb notify;
	void *userdata;

	
	bool is_eth_ready;
};


enum ipa_eth_client_type {
	IPA_ETH_CLIENT_AQC107,
	IPA_ETH_CLIENT_AQC113,
	IPA_ETH_CLIENT_RTK8111K,
	IPA_ETH_CLIENT_RTK8125B,
	IPA_ETH_CLIENT_NTN,
	IPA_ETH_CLIENT_EMAC,
	IPA_ETH_CLIENT_NTN3,
	IPA_ETH_CLIENT_IEMAC,
	IPA_ETH_CLIENT_MAX,
};


enum ipa_eth_pipe_traffic_type {
	IPA_ETH_PIPE_BEST_EFFORT,
	IPA_ETH_PIPE_LOW_LATENCY,
	IPA_ETH_PIPE_TRAFFIC_TYPE_MAX,
};


enum ipa_eth_pipe_direction {
	IPA_ETH_PIPE_DIR_TX,
	IPA_ETH_PIPE_DIR_RX,
	IPA_ETH_PIPE_DIR_MAX,
};

#define IPA_ETH_INST_ID_MAX (2)


struct ipa_eth_ntn_setup_info {
	phys_addr_t bar_addr;
	phys_addr_t tail_ptr_offs;
	uint16_t ioc_mod_threshold;
};


struct ipa_eth_aqc_setup_info {
	phys_addr_t bar_addr;
	phys_addr_t head_ptr_offs;
	u8 aqc_ch;
	phys_addr_t dest_tail_ptr_offs;
};



struct ipa_eth_realtek_setup_info {
	phys_addr_t bar_addr;
	u32 bar_size;
	u8 queue_number;
	phys_addr_t dest_tail_ptr_offs;
};


struct ipa_eth_buff_smmu_map {
	dma_addr_t iova;
	phys_addr_t pa;
};


struct ipa_eth_pipe_setup_info {
	
	bool is_transfer_ring_valid;
	dma_addr_t  transfer_ring_base;
	struct sg_table *transfer_ring_sgt;
	u32 transfer_ring_size;

	
	bool is_buffer_pool_valid;
	dma_addr_t buffer_pool_base_addr;
	struct sg_table *buffer_pool_base_sgt;

	
	u32 data_buff_list_size;
	struct ipa_eth_buff_smmu_map *data_buff_list;
	u32 fix_buffer_size;

	
	ipa_notify_cb notify;
	void *priv;

	
	union {
		struct ipa_eth_aqc_setup_info aqc;
		struct ipa_eth_realtek_setup_info rtk;
		struct ipa_eth_ntn_setup_info ntn;
	} client_info;

	
	phys_addr_t db_pa;
	u32 db_val;
};


struct ipa_eth_client_pipe_info {
	struct list_head link;
	enum ipa_eth_pipe_direction dir;
	struct ipa_eth_pipe_setup_info info;
	struct ipa_eth_client *client_info;

	
	ipa_eth_hdl_t pipe_hdl;
};


struct ipa_eth_client {
	enum ipa_eth_client_type client_type;
	u8 inst_id;

	
	enum ipa_eth_pipe_traffic_type traffic_type;
	struct list_head pipe_list;

	
	void *priv;
	bool test;

	
	struct net_device *net_dev;
};


struct ipa_eth_perf_profile {
	u32 max_supported_bw_mbps;
};


struct ipa_eth_hdr_info {
	u8 *hdr;
	u8 hdr_len;
	u8 dst_mac_addr_offset;
	enum ipa_hdr_l2_type hdr_type;
};


struct ipa_eth_intf_info {
	struct ipa_eth_client *client;

	
	bool is_conn_evt;

	
	struct net_device *net_dev;
};

int ipa_eth_register_ready_cb(struct ipa_eth_ready *ready_info);
int ipa_eth_unregister_ready_cb(struct ipa_eth_ready *ready_info);
int ipa_eth_client_conn_pipes(struct ipa_eth_client *client);
int ipa_eth_client_disconn_pipes(struct ipa_eth_client *client);
int ipa_eth_client_reg_intf(struct ipa_eth_intf_info *intf);
int ipa_eth_client_unreg_intf(struct ipa_eth_intf_info *intf);
int ipa_eth_client_set_perf_profile(struct ipa_eth_client *client,
	struct ipa_eth_perf_profile *profile);
enum ipa_client_type ipa_eth_get_ipa_client_type_from_eth_type(
	enum ipa_eth_client_type eth_client_type, enum ipa_eth_pipe_direction dir);
bool ipa_eth_client_exist(
	enum ipa_eth_client_type eth_client_type, int inst_id);

#endif // _IPA_ETH_H_
