unplugged-kernel/drivers/misc/mediatek/eccci/port/port_t.h

165 lines
5.4 KiB
C
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2016 MediaTek Inc.
*/
#ifndef __PORT_T_H__
#define __PORT_T_H__
#include "ccci_core.h"
/* packet will be dropped if port's Rx buffer full */
#define PORT_F_ALLOW_DROP (1<<0)
/* rx buffer has been full once */
#define PORT_F_RX_FULLED (1<<1)
/* CCCI header will be provided by user, but not by CCCI */
#define PORT_F_USER_HEADER (1<<2)
/* Rx queue only has this one port */
#define PORT_F_RX_EXCLUSIVE (1<<3)
/* Check whether need remove ccci header while recv skb*/
#define PORT_F_ADJUST_HEADER (1<<4)
/* Enable port channel traffic*/
#define PORT_F_CH_TRAFFIC (1<<5)
/* Dump raw data if CH_TRAFFIC set*/
#define PORT_F_DUMP_RAW_DATA (1<<6)
/* Need export char dev node for userspace*/
#define PORT_F_WITH_CHAR_NODE (1<<7)
/* reused for net tx, Data queue, same bit as RX_FULLED */
#define PORT_F_TX_DATA_FULLED (1<<1)
#define PORT_F_TX_ACK_FULLED (1<<8)
/*Can be clean when MD is invalid*/
#define PORT_F_CLEAN (1<<9)
/*Dump pkt of ccmni*/
#define PORT_F_NET_DUMP (1<<10)
enum {
PORT_DBG_DUMP_RILD = 0,
PORT_DBG_DUMP_AUDIO,
PORT_DBG_DUMP_IMS,
};
struct port_t;
struct port_ops {
/* must-have */
int (*init)(struct port_t *port);
int (*recv_skb)(struct port_t *port, struct sk_buff *skb);
/* optional */
int (*recv_match)(struct port_t *port, struct sk_buff *skb);
void (*md_state_notify)(struct port_t *port, unsigned int md_state);
void (*queue_state_notify)(struct port_t *port, int dir, int qno,
unsigned int qstate);
void (*dump_info)(struct port_t *port, unsigned int flag);
};
typedef void (*port_skb_handler)(struct port_t *port, struct sk_buff *skb);
struct port_t {
/* don't change the sequence unless
* you modified modem drivers as well
*/
/* identity */
enum CCCI_CH tx_ch;
enum CCCI_CH rx_ch;
/*
*
* here is a nasty trick, we assume no modem provide
* more than 0xF0 queues, so we use
* the lower 4 bit to smuggle info for network ports.
* Attention, in this trick we assume hardware queue index
* for net port will not exceed 0xF.
* check NET_ACK_TXQ_INDEX@port_net.c
*/
unsigned char txq_index;
unsigned char rxq_index;
unsigned char txq_exp_index;
unsigned char rxq_exp_index;
unsigned char hif_id;
unsigned short flags;
struct port_ops *ops;
/* device node related */
unsigned int minor;
char *name;
/* un-initiallized in defination, always put them at the end */
int md_id;
void *port_proxy;
void *private_data;
atomic_t usage_cnt;
struct list_head entry;
struct list_head exp_entry;
struct list_head queue_entry;
unsigned int major; /*dynamic alloc*/
unsigned int minor_base;
/*
* the Tx and Rx flow are asymmetric due to ports are
* mutilplexed on queues.
* Tx: data block are sent directly to queue's list,
* so port won't maitain a Tx list. It only
* provide a wait_queue_head for blocking write.
* Rx: due to modem needs to dispatch Rx packet
* as quickly as possible, so port needs a
* Rx list to hold packets.
*/
struct sk_buff_head rx_skb_list;
/* add high prio rx list for udc */
struct sk_buff_head rx_skb_list_hp;
unsigned char skb_from_pool;
spinlock_t rx_req_lock;
wait_queue_head_t rx_wq; /* for uplayer user */
int rx_length;
int rx_length_th;
struct wakeup_source *rx_wakelock;
unsigned int tx_busy_count;
unsigned int rx_busy_count;
int interception;
unsigned int rx_pkg_cnt;
unsigned int rx_drop_cnt;
unsigned int tx_pkg_cnt;
port_skb_handler skb_handler;
struct sk_buff_head port_rx_list;
atomic_t is_up; /*for ccmni status*/
spinlock_t flag_lock;
};
/****************************************************************************/
/* API Region called by ccci port object */
/****************************************************************************/
/*
*This API used to some port create kthread handle,
*which have same kthread handle flow.
*/
int port_kthread_handler(void *arg);
/*
*This API used to some port to receive native HIF RX data,
*which have same RX receive flow.
*/
int port_recv_skb(struct port_t *port, struct sk_buff *skb);
int port_user_register(struct port_t *port);
int port_user_unregister(struct port_t *port);
int port_ask_more_req_to_md(struct port_t *port);
int port_write_room_to_md(struct port_t *port);
void port_ch_dump(struct port_t *port, int dir, void *msg_buf, int len);
int port_get_capability(int md_id);
struct port_t *port_get_by_node(int major, int minor);
struct port_t *port_get_by_minor(int md_id, int minor);
struct port_t *port_get_by_channel(int md_id, enum CCCI_CH ch);
int port_send_skb_to_md(struct port_t *port, struct sk_buff *skb,
int blocking);
int port_net_send_skb_to_md(struct port_t *port, int is_ack,
struct sk_buff *skb);
int port_send_msg_to_md(struct port_t *port, unsigned int msg,
unsigned int resv, int blocking);
int port_dev_open(struct inode *inode, struct file *file);
int port_dev_close(struct inode *inode, struct file *file);
ssize_t port_dev_read(struct file *file, char *buf, size_t count,
loff_t *ppos);
ssize_t port_dev_write(struct file *file, const char __user *buf, size_t count,
loff_t *ppos);
long port_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
#ifdef CONFIG_COMPAT
long port_dev_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
#endif
int port_dev_mmap(struct file *fp, struct vm_area_struct *vma);
int find_port_by_channel(int channel, struct port_t **port);
int send_new_time_to_new_md(int md_id, int tz);
#endif /* __PORT_T_H__ */