xref: /openbmc/linux/drivers/net/wwan/t7xx/t7xx_port.h (revision ba2274dc)
148cc2f5eSHaijun Liu /* SPDX-License-Identifier: GPL-2.0-only
248cc2f5eSHaijun Liu  *
348cc2f5eSHaijun Liu  * Copyright (c) 2021, MediaTek Inc.
448cc2f5eSHaijun Liu  * Copyright (c) 2021-2022, Intel Corporation.
548cc2f5eSHaijun Liu  *
648cc2f5eSHaijun Liu  * Authors:
748cc2f5eSHaijun Liu  *  Haijun Liu <haijun.liu@mediatek.com>
848cc2f5eSHaijun Liu  *  Moises Veleta <moises.veleta@intel.com>
948cc2f5eSHaijun Liu  *  Ricardo Martinez <ricardo.martinez@linux.intel.com>
1048cc2f5eSHaijun Liu  *
1148cc2f5eSHaijun Liu  * Contributors:
1248cc2f5eSHaijun Liu  *  Amir Hanania <amir.hanania@intel.com>
1348cc2f5eSHaijun Liu  *  Andy Shevchenko <andriy.shevchenko@linux.intel.com>
1448cc2f5eSHaijun Liu  *  Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
1548cc2f5eSHaijun Liu  *  Eliot Lee <eliot.lee@intel.com>
1648cc2f5eSHaijun Liu  */
1748cc2f5eSHaijun Liu 
1848cc2f5eSHaijun Liu #ifndef __T7XX_PORT_H__
1948cc2f5eSHaijun Liu #define __T7XX_PORT_H__
2048cc2f5eSHaijun Liu 
2148cc2f5eSHaijun Liu #include <linux/bits.h>
2248cc2f5eSHaijun Liu #include <linux/device.h>
2348cc2f5eSHaijun Liu #include <linux/mutex.h>
2448cc2f5eSHaijun Liu #include <linux/sched.h>
2548cc2f5eSHaijun Liu #include <linux/skbuff.h>
2648cc2f5eSHaijun Liu #include <linux/spinlock.h>
2748cc2f5eSHaijun Liu #include <linux/types.h>
2848cc2f5eSHaijun Liu #include <linux/wait.h>
2948cc2f5eSHaijun Liu #include <linux/wwan.h>
3048cc2f5eSHaijun Liu 
3148cc2f5eSHaijun Liu #include "t7xx_hif_cldma.h"
3248cc2f5eSHaijun Liu #include "t7xx_pci.h"
3348cc2f5eSHaijun Liu 
3448cc2f5eSHaijun Liu #define PORT_CH_ID_MASK		GENMASK(7, 0)
3548cc2f5eSHaijun Liu 
3648cc2f5eSHaijun Liu /* Channel ID and Message ID definitions.
3748cc2f5eSHaijun Liu  * The channel number consists of peer_id(15:12) , channel_id(11:0)
3848cc2f5eSHaijun Liu  * peer_id:
39*ba2274dcSJose Ignacio Tornos Martinez  * 0:reserved, 1: to AP, 2: to MD
4048cc2f5eSHaijun Liu  */
4148cc2f5eSHaijun Liu enum port_ch {
42*ba2274dcSJose Ignacio Tornos Martinez 	/* to AP */
43*ba2274dcSJose Ignacio Tornos Martinez 	PORT_CH_AP_CONTROL_RX = 0x1000,
44*ba2274dcSJose Ignacio Tornos Martinez 	PORT_CH_AP_CONTROL_TX = 0x1001,
45*ba2274dcSJose Ignacio Tornos Martinez 
4648cc2f5eSHaijun Liu 	/* to MD */
4748cc2f5eSHaijun Liu 	PORT_CH_CONTROL_RX = 0x2000,
4848cc2f5eSHaijun Liu 	PORT_CH_CONTROL_TX = 0x2001,
4948cc2f5eSHaijun Liu 	PORT_CH_UART1_RX = 0x2006,	/* META */
5048cc2f5eSHaijun Liu 	PORT_CH_UART1_TX = 0x2008,
5148cc2f5eSHaijun Liu 	PORT_CH_UART2_RX = 0x200a,	/* AT */
5248cc2f5eSHaijun Liu 	PORT_CH_UART2_TX = 0x200c,
5348cc2f5eSHaijun Liu 	PORT_CH_MD_LOG_RX = 0x202a,	/* MD logging */
5448cc2f5eSHaijun Liu 	PORT_CH_MD_LOG_TX = 0x202b,
5548cc2f5eSHaijun Liu 	PORT_CH_LB_IT_RX = 0x203e,	/* Loop back test */
5648cc2f5eSHaijun Liu 	PORT_CH_LB_IT_TX = 0x203f,
5748cc2f5eSHaijun Liu 	PORT_CH_STATUS_RX = 0x2043,	/* Status events */
5848cc2f5eSHaijun Liu 	PORT_CH_MIPC_RX = 0x20ce,	/* MIPC */
5948cc2f5eSHaijun Liu 	PORT_CH_MIPC_TX = 0x20cf,
6048cc2f5eSHaijun Liu 	PORT_CH_MBIM_RX = 0x20d0,
6148cc2f5eSHaijun Liu 	PORT_CH_MBIM_TX = 0x20d1,
6248cc2f5eSHaijun Liu 	PORT_CH_DSS0_RX = 0x20d2,
6348cc2f5eSHaijun Liu 	PORT_CH_DSS0_TX = 0x20d3,
6448cc2f5eSHaijun Liu 	PORT_CH_DSS1_RX = 0x20d4,
6548cc2f5eSHaijun Liu 	PORT_CH_DSS1_TX = 0x20d5,
6648cc2f5eSHaijun Liu 	PORT_CH_DSS2_RX = 0x20d6,
6748cc2f5eSHaijun Liu 	PORT_CH_DSS2_TX = 0x20d7,
6848cc2f5eSHaijun Liu 	PORT_CH_DSS3_RX = 0x20d8,
6948cc2f5eSHaijun Liu 	PORT_CH_DSS3_TX = 0x20d9,
7048cc2f5eSHaijun Liu 	PORT_CH_DSS4_RX = 0x20da,
7148cc2f5eSHaijun Liu 	PORT_CH_DSS4_TX = 0x20db,
7248cc2f5eSHaijun Liu 	PORT_CH_DSS5_RX = 0x20dc,
7348cc2f5eSHaijun Liu 	PORT_CH_DSS5_TX = 0x20dd,
7448cc2f5eSHaijun Liu 	PORT_CH_DSS6_RX = 0x20de,
7548cc2f5eSHaijun Liu 	PORT_CH_DSS6_TX = 0x20df,
7648cc2f5eSHaijun Liu 	PORT_CH_DSS7_RX = 0x20e0,
7748cc2f5eSHaijun Liu 	PORT_CH_DSS7_TX = 0x20e1,
7848cc2f5eSHaijun Liu };
7948cc2f5eSHaijun Liu 
8048cc2f5eSHaijun Liu struct t7xx_port;
8148cc2f5eSHaijun Liu struct port_ops {
8248cc2f5eSHaijun Liu 	int (*init)(struct t7xx_port *port);
8348cc2f5eSHaijun Liu 	int (*recv_skb)(struct t7xx_port *port, struct sk_buff *skb);
8448cc2f5eSHaijun Liu 	void (*md_state_notify)(struct t7xx_port *port, unsigned int md_state);
8548cc2f5eSHaijun Liu 	void (*uninit)(struct t7xx_port *port);
8648cc2f5eSHaijun Liu 	int (*enable_chl)(struct t7xx_port *port);
8748cc2f5eSHaijun Liu 	int (*disable_chl)(struct t7xx_port *port);
8848cc2f5eSHaijun Liu };
8948cc2f5eSHaijun Liu 
9048cc2f5eSHaijun Liu struct t7xx_port_conf {
9148cc2f5eSHaijun Liu 	enum port_ch		tx_ch;
9248cc2f5eSHaijun Liu 	enum port_ch		rx_ch;
9348cc2f5eSHaijun Liu 	unsigned char		txq_index;
9448cc2f5eSHaijun Liu 	unsigned char		rxq_index;
9548cc2f5eSHaijun Liu 	unsigned char		txq_exp_index;
9648cc2f5eSHaijun Liu 	unsigned char		rxq_exp_index;
9748cc2f5eSHaijun Liu 	enum cldma_id		path_id;
9848cc2f5eSHaijun Liu 	struct port_ops		*ops;
9948cc2f5eSHaijun Liu 	char			*name;
10048cc2f5eSHaijun Liu 	enum wwan_port_type	port_type;
10148cc2f5eSHaijun Liu };
10248cc2f5eSHaijun Liu 
10348cc2f5eSHaijun Liu struct t7xx_port {
10448cc2f5eSHaijun Liu 	/* Members not initialized in definition */
10548cc2f5eSHaijun Liu 	const struct t7xx_port_conf	*port_conf;
10648cc2f5eSHaijun Liu 	struct t7xx_pci_dev		*t7xx_dev;
10748cc2f5eSHaijun Liu 	struct device			*dev;
10848cc2f5eSHaijun Liu 	u16				seq_nums[2];	/* TX/RX sequence numbers */
10948cc2f5eSHaijun Liu 	atomic_t			usage_cnt;
11048cc2f5eSHaijun Liu 	struct				list_head entry;
11148cc2f5eSHaijun Liu 	struct				list_head queue_entry;
11248cc2f5eSHaijun Liu 	/* TX and RX flows are asymmetric since ports are multiplexed on
11348cc2f5eSHaijun Liu 	 * queues.
11448cc2f5eSHaijun Liu 	 *
11548cc2f5eSHaijun Liu 	 * TX: data blocks are sent directly to a queue. Each port
11648cc2f5eSHaijun Liu 	 * does not maintain a TX list; instead, they only provide
11748cc2f5eSHaijun Liu 	 * a wait_queue_head for blocking writes.
11848cc2f5eSHaijun Liu 	 *
11948cc2f5eSHaijun Liu 	 * RX: Each port uses a RX list to hold packets,
12048cc2f5eSHaijun Liu 	 * allowing the modem to dispatch RX packet as quickly as possible.
12148cc2f5eSHaijun Liu 	 */
12248cc2f5eSHaijun Liu 	struct sk_buff_head		rx_skb_list;
12348cc2f5eSHaijun Liu 	spinlock_t			port_update_lock; /* Protects port configuration */
12448cc2f5eSHaijun Liu 	wait_queue_head_t		rx_wq;
12548cc2f5eSHaijun Liu 	int				rx_length_th;
12648cc2f5eSHaijun Liu 	bool				chan_enable;
12748cc2f5eSHaijun Liu 	struct task_struct		*thread;
128fece7a8cSM Chetan Kumar 	union {
129fece7a8cSM Chetan Kumar 		struct {
130fece7a8cSM Chetan Kumar 			struct wwan_port		*wwan_port;
131fece7a8cSM Chetan Kumar 		} wwan;
1323349e4a4SM Chetan Kumar 		struct {
1333349e4a4SM Chetan Kumar 			struct rchan			*relaych;
1343349e4a4SM Chetan Kumar 		} log;
135fece7a8cSM Chetan Kumar 	};
13648cc2f5eSHaijun Liu };
13748cc2f5eSHaijun Liu 
13848cc2f5eSHaijun Liu struct sk_buff *t7xx_port_alloc_skb(int payload);
139da45d256SHaijun Liu struct sk_buff *t7xx_ctrl_alloc_skb(int payload);
14048cc2f5eSHaijun Liu int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb);
14148cc2f5eSHaijun Liu int t7xx_port_send_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int pkt_header,
14248cc2f5eSHaijun Liu 		       unsigned int ex_msg);
143da45d256SHaijun Liu int t7xx_port_send_ctl_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int msg,
144da45d256SHaijun Liu 			   unsigned int ex_msg);
14548cc2f5eSHaijun Liu 
14648cc2f5eSHaijun Liu #endif /* __T7XX_PORT_H__ */
147