summaryrefslogtreecommitdiffstats
path: root/drivers/net/wwan/t7xx/t7xx_port.h
blob: dc4133eb433a01d17358941473f904b881951504 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* SPDX-License-Identifier: GPL-2.0-only
 *
 * Copyright (c) 2021, MediaTek Inc.
 * Copyright (c) 2021-2022, Intel Corporation.
 *
 * Authors:
 *  Haijun Liu <haijun.liu@mediatek.com>
 *  Moises Veleta <moises.veleta@intel.com>
 *  Ricardo Martinez <ricardo.martinez@linux.intel.com>
 *
 * Contributors:
 *  Amir Hanania <amir.hanania@intel.com>
 *  Andy Shevchenko <andriy.shevchenko@linux.intel.com>
 *  Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
 *  Eliot Lee <eliot.lee@intel.com>
 */

#ifndef __T7XX_PORT_H__
#define __T7XX_PORT_H__

#include <linux/bits.h>
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/wait.h>
#include <linux/wwan.h>

#include "t7xx_hif_cldma.h"
#include "t7xx_pci.h"

#define PORT_CH_ID_MASK		GENMASK(7, 0)

/* Channel ID and Message ID definitions.
 * The channel number consists of peer_id(15:12) , channel_id(11:0)
 * peer_id:
 * 0:reserved, 1: to sAP, 2: to MD
 */
enum port_ch {
	/* to MD */
	PORT_CH_CONTROL_RX = 0x2000,
	PORT_CH_CONTROL_TX = 0x2001,
	PORT_CH_UART1_RX = 0x2006,	/* META */
	PORT_CH_UART1_TX = 0x2008,
	PORT_CH_UART2_RX = 0x200a,	/* AT */
	PORT_CH_UART2_TX = 0x200c,
	PORT_CH_MD_LOG_RX = 0x202a,	/* MD logging */
	PORT_CH_MD_LOG_TX = 0x202b,
	PORT_CH_LB_IT_RX = 0x203e,	/* Loop back test */
	PORT_CH_LB_IT_TX = 0x203f,
	PORT_CH_STATUS_RX = 0x2043,	/* Status events */
	PORT_CH_MIPC_RX = 0x20ce,	/* MIPC */
	PORT_CH_MIPC_TX = 0x20cf,
	PORT_CH_MBIM_RX = 0x20d0,
	PORT_CH_MBIM_TX = 0x20d1,
	PORT_CH_DSS0_RX = 0x20d2,
	PORT_CH_DSS0_TX = 0x20d3,
	PORT_CH_DSS1_RX = 0x20d4,
	PORT_CH_DSS1_TX = 0x20d5,
	PORT_CH_DSS2_RX = 0x20d6,
	PORT_CH_DSS2_TX = 0x20d7,
	PORT_CH_DSS3_RX = 0x20d8,
	PORT_CH_DSS3_TX = 0x20d9,
	PORT_CH_DSS4_RX = 0x20da,
	PORT_CH_DSS4_TX = 0x20db,
	PORT_CH_DSS5_RX = 0x20dc,
	PORT_CH_DSS5_TX = 0x20dd,
	PORT_CH_DSS6_RX = 0x20de,
	PORT_CH_DSS6_TX = 0x20df,
	PORT_CH_DSS7_RX = 0x20e0,
	PORT_CH_DSS7_TX = 0x20e1,
};

struct t7xx_port;
struct port_ops {
	int (*init)(struct t7xx_port *port);
	int (*recv_skb)(struct t7xx_port *port, struct sk_buff *skb);
	void (*md_state_notify)(struct t7xx_port *port, unsigned int md_state);
	void (*uninit)(struct t7xx_port *port);
	int (*enable_chl)(struct t7xx_port *port);
	int (*disable_chl)(struct t7xx_port *port);
};

struct t7xx_port_conf {
	enum port_ch		tx_ch;
	enum port_ch		rx_ch;
	unsigned char		txq_index;
	unsigned char		rxq_index;
	unsigned char		txq_exp_index;
	unsigned char		rxq_exp_index;
	enum cldma_id		path_id;
	struct port_ops		*ops;
	char			*name;
	enum wwan_port_type	port_type;
};

struct t7xx_port {
	/* Members not initialized in definition */
	const struct t7xx_port_conf	*port_conf;
	struct wwan_port		*wwan_port;
	struct t7xx_pci_dev		*t7xx_dev;
	struct device			*dev;
	u16				seq_nums[2];	/* TX/RX sequence numbers */
	atomic_t			usage_cnt;
	struct				list_head entry;
	struct				list_head queue_entry;
	/* TX and RX flows are asymmetric since ports are multiplexed on
	 * queues.
	 *
	 * TX: data blocks are sent directly to a queue. Each port
	 * does not maintain a TX list; instead, they only provide
	 * a wait_queue_head for blocking writes.
	 *
	 * RX: Each port uses a RX list to hold packets,
	 * allowing the modem to dispatch RX packet as quickly as possible.
	 */
	struct sk_buff_head		rx_skb_list;
	spinlock_t			port_update_lock; /* Protects port configuration */
	wait_queue_head_t		rx_wq;
	int				rx_length_th;
	bool				chan_enable;
	struct task_struct		*thread;
};

struct sk_buff *t7xx_port_alloc_skb(int payload);
struct sk_buff *t7xx_ctrl_alloc_skb(int payload);
int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb);
int t7xx_port_send_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int pkt_header,
		       unsigned int ex_msg);
int t7xx_port_send_ctl_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int msg,
			   unsigned int ex_msg);

#endif /* __T7XX_PORT_H__ */