summaryrefslogtreecommitdiffstats
path: root/drivers/net/wwan/t7xx/t7xx_hif_dpmaif.h
blob: 1225ca0ed51e890f2ab8464a421350df2f87b7b9 (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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/* SPDX-License-Identifier: GPL-2.0-only
 *
 * Copyright (c) 2021, MediaTek Inc.
 * Copyright (c) 2021-2022, Intel Corporation.
 *
 * Authors:
 *  Amir Hanania <amir.hanania@intel.com>
 *  Haijun Liu <haijun.liu@mediatek.com>
 *  Moises Veleta <moises.veleta@intel.com>
 *  Ricardo Martinez <ricardo.martinez@linux.intel.com>
 *
 * Contributors:
 *  Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com>
 *  Eliot Lee <eliot.lee@intel.com>
 *  Sreehari Kancharla <sreehari.kancharla@intel.com>
 */

#ifndef __T7XX_HIF_DPMAIF_H__
#define __T7XX_HIF_DPMAIF_H__

#include <linux/bitmap.h>
#include <linux/mm_types.h>
#include <linux/sched.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/wait.h>
#include <linux/workqueue.h>

#include "t7xx_dpmaif.h"
#include "t7xx_pci.h"
#include "t7xx_state_monitor.h"

/* SKB control buffer */
struct t7xx_skb_cb {
	u8	netif_idx;
	u8	txq_number;
	u8	rx_pkt_type;
};

#define T7XX_SKB_CB(__skb)	((struct t7xx_skb_cb *)(__skb)->cb)

enum dpmaif_rdwr {
	DPMAIF_READ,
	DPMAIF_WRITE,
};

/* Structure of DL BAT */
struct dpmaif_cur_rx_skb_info {
	bool			msg_pit_received;
	struct sk_buff		*cur_skb;
	unsigned int		cur_chn_idx;
	unsigned int		check_sum;
	unsigned int		pit_dp;
	unsigned int		pkt_type;
	int			err_payload;
};

struct dpmaif_bat {
	unsigned int		p_buffer_addr;
	unsigned int		buffer_addr_ext;
};

struct dpmaif_bat_skb {
	struct sk_buff		*skb;
	dma_addr_t		data_bus_addr;
	unsigned int		data_len;
};

struct dpmaif_bat_page {
	struct page		*page;
	dma_addr_t		data_bus_addr;
	unsigned int		offset;
	unsigned int		data_len;
};

enum bat_type {
	BAT_TYPE_NORMAL,
	BAT_TYPE_FRAG,
};

struct dpmaif_bat_request {
	void			*bat_base;
	dma_addr_t		bat_bus_addr;
	unsigned int		bat_size_cnt;
	unsigned int		bat_wr_idx;
	unsigned int		bat_release_rd_idx;
	void			*bat_skb;
	unsigned int		pkt_buf_sz;
	unsigned long		*bat_bitmap;
	atomic_t		refcnt;
	spinlock_t		mask_lock; /* Protects BAT mask */
	enum bat_type		type;
};

struct dpmaif_rx_queue {
	unsigned int		index;
	bool			que_started;
	unsigned int		budget;

	void			*pit_base;
	dma_addr_t		pit_bus_addr;
	unsigned int		pit_size_cnt;

	unsigned int		pit_rd_idx;
	unsigned int		pit_wr_idx;
	unsigned int		pit_release_rd_idx;

	struct dpmaif_bat_request *bat_req;
	struct dpmaif_bat_request *bat_frag;

	wait_queue_head_t	rx_wq;
	struct task_struct	*rx_thread;
	struct sk_buff_head	skb_list;
	unsigned int		skb_list_max_len;

	struct workqueue_struct	*worker;
	struct work_struct	dpmaif_rxq_work;

	atomic_t		rx_processing;

	struct dpmaif_ctrl	*dpmaif_ctrl;
	unsigned int		expect_pit_seq;
	unsigned int		pit_remain_release_cnt;
	struct dpmaif_cur_rx_skb_info rx_data_info;
};

struct dpmaif_tx_queue {
	unsigned int		index;
	bool			que_started;
	atomic_t		tx_budget;
	void			*drb_base;
	dma_addr_t		drb_bus_addr;
	unsigned int		drb_size_cnt;
	unsigned int		drb_wr_idx;
	unsigned int		drb_rd_idx;
	unsigned int		drb_release_rd_idx;
	void			*drb_skb_base;
	wait_queue_head_t	req_wq;
	struct workqueue_struct	*worker;
	struct work_struct	dpmaif_tx_work;
	spinlock_t		tx_lock; /* Protects txq DRB */
	atomic_t		tx_processing;

	struct dpmaif_ctrl	*dpmaif_ctrl;
	struct sk_buff_head	tx_skb_head;
};

struct dpmaif_isr_para {
	struct dpmaif_ctrl	*dpmaif_ctrl;
	unsigned char		pcie_int;
	unsigned char		dlq_id;
};

enum dpmaif_state {
	DPMAIF_STATE_MIN,
	DPMAIF_STATE_PWROFF,
	DPMAIF_STATE_PWRON,
	DPMAIF_STATE_EXCEPTION,
	DPMAIF_STATE_MAX
};

enum dpmaif_txq_state {
	DMPAIF_TXQ_STATE_IRQ,
	DMPAIF_TXQ_STATE_FULL,
};

struct dpmaif_callbacks {
	void (*state_notify)(struct t7xx_pci_dev *t7xx_dev,
			     enum dpmaif_txq_state state, int txq_number);
	void (*recv_skb)(struct t7xx_pci_dev *t7xx_dev, struct sk_buff *skb);
};

struct dpmaif_ctrl {
	struct device			*dev;
	struct t7xx_pci_dev		*t7xx_dev;
	struct md_pm_entity		dpmaif_pm_entity;
	enum dpmaif_state		state;
	bool				dpmaif_sw_init_done;
	struct dpmaif_hw_info		hw_info;
	struct dpmaif_tx_queue		txq[DPMAIF_TXQ_NUM];
	struct dpmaif_rx_queue		rxq[DPMAIF_RXQ_NUM];

	unsigned char			rxq_int_mapping[DPMAIF_RXQ_NUM];
	struct dpmaif_isr_para		isr_para[DPMAIF_RXQ_NUM];

	struct dpmaif_bat_request	bat_req;
	struct dpmaif_bat_request	bat_frag;
	struct workqueue_struct		*bat_release_wq;
	struct work_struct		bat_release_work;

	wait_queue_head_t		tx_wq;
	struct task_struct		*tx_thread;

	struct dpmaif_callbacks		*callbacks;
};

struct dpmaif_ctrl *t7xx_dpmaif_hif_init(struct t7xx_pci_dev *t7xx_dev,
					 struct dpmaif_callbacks *callbacks);
void t7xx_dpmaif_hif_exit(struct dpmaif_ctrl *dpmaif_ctrl);
int t7xx_dpmaif_md_state_callback(struct dpmaif_ctrl *dpmaif_ctrl, enum md_state state);
unsigned int t7xx_ring_buf_get_next_wr_idx(unsigned int buf_len, unsigned int buf_idx);
unsigned int t7xx_ring_buf_rd_wr_count(unsigned int total_cnt, unsigned int rd_idx,
				       unsigned int wr_idx, enum dpmaif_rdwr);

#endif /* __T7XX_HIF_DPMAIF_H__ */