summaryrefslogtreecommitdiff
path: root/drivers/staging/fsl_ppfe/pfe_hif.h
blob: 6e36f0c1f4ffcc235a803bfa468fd40eece4c79f (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
207
208
209
210
211
/*
 * Copyright 2015-2016 Freescale Semiconductor, Inc.
 * Copyright 2017 NXP
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _PFE_HIF_H_
#define _PFE_HIF_H_

#include <linux/netdevice.h>

#define HIF_NAPI_STATS

#define HIF_CLIENT_QUEUES_MAX	16
#define HIF_RX_POLL_WEIGHT	64

#define HIF_RX_PKT_MIN_SIZE 0x800 /* 2KB */
#define HIF_RX_PKT_MIN_SIZE_MASK ~(HIF_RX_PKT_MIN_SIZE - 1)
#define ROUND_MIN_RX_SIZE(_sz) (((_sz) + (HIF_RX_PKT_MIN_SIZE - 1)) \
					& HIF_RX_PKT_MIN_SIZE_MASK)
#define PRESENT_OFST_IN_PAGE(_buf) (((unsigned long int)(_buf) & (PAGE_SIZE \
					- 1)) & HIF_RX_PKT_MIN_SIZE_MASK)

enum {
	NAPI_SCHED_COUNT = 0,
	NAPI_POLL_COUNT,
	NAPI_PACKET_COUNT,
	NAPI_DESC_COUNT,
	NAPI_FULL_BUDGET_COUNT,
	NAPI_CLIENT_FULL_COUNT,
	NAPI_MAX_COUNT
};

/*
 * HIF_TX_DESC_NT value should be always greter than 4,
 * Otherwise HIF_TX_POLL_MARK will become zero.
 */
#define HIF_RX_DESC_NT		256
#define HIF_TX_DESC_NT		2048

#define HIF_FIRST_BUFFER	BIT(0)
#define HIF_LAST_BUFFER		BIT(1)
#define HIF_DONT_DMA_MAP	BIT(2)
#define HIF_DATA_VALID		BIT(3)
#define HIF_TSO			BIT(4)

enum {
	PFE_CL_GEM0 = 0,
	PFE_CL_GEM1,
	HIF_CLIENTS_MAX
};

/*structure to store client queue info */
struct hif_rx_queue {
	struct rx_queue_desc *base;
	u32	size;
	u32	write_idx;
};

struct hif_tx_queue {
	struct tx_queue_desc *base;
	u32	size;
	u32	ack_idx;
};

/*Structure to store the client info */
struct hif_client {
	int	rx_qn;
	struct hif_rx_queue	rx_q[HIF_CLIENT_QUEUES_MAX];
	int	tx_qn;
	struct hif_tx_queue	tx_q[HIF_CLIENT_QUEUES_MAX];
};

/*HIF hardware buffer descriptor */
struct hif_desc {
	u32 ctrl;
	u32 status;
	u32 data;
	u32 next;
};

struct __hif_desc {
	u32 ctrl;
	u32 status;
	u32 data;
};

struct hif_desc_sw {
	dma_addr_t data;
	u16 len;
	u8 client_id;
	u8 q_no;
	u16 flags;
};

struct hif_hdr {
	u8 client_id;
	u8 q_num;
	u16 client_ctrl;
	u16 client_ctrl1;
};

struct __hif_hdr {
	union {
		struct hif_hdr hdr;
		u32 word[2];
	};
};

struct hif_ipsec_hdr {
	u16	sa_handle[2];
} __packed;

/*  HIF_CTRL_TX... defines */
#define HIF_CTRL_TX_CHECKSUM		BIT(2)

/*  HIF_CTRL_RX... defines */
#define HIF_CTRL_RX_OFFSET_OFST         (24)
#define HIF_CTRL_RX_CHECKSUMMED		BIT(2)
#define HIF_CTRL_RX_CONTINUED		BIT(1)

struct pfe_hif {
	/* To store registered clients in hif layer */
	struct hif_client client[HIF_CLIENTS_MAX];
	struct hif_shm *shm;
	int	irq;

	void	*descr_baseaddr_v;
	unsigned long	descr_baseaddr_p;

	struct hif_desc *rx_base;
	u32	rx_ring_size;
	u32	rxtoclean_index;
	void	*rx_buf_addr[HIF_RX_DESC_NT];
	int	rx_buf_len[HIF_RX_DESC_NT];
	unsigned int qno;
	unsigned int client_id;
	unsigned int client_ctrl;
	unsigned int started;

	struct hif_desc *tx_base;
	u32	tx_ring_size;
	u32	txtosend;
	u32	txtoclean;
	u32	txavail;
	u32	txtoflush;
	struct hif_desc_sw tx_sw_queue[HIF_TX_DESC_NT];

/* tx_lock synchronizes hif packet tx as well as pfe_hif structure access */
	spinlock_t tx_lock;
/* lock synchronizes hif rx queue processing */
	spinlock_t lock;
	struct net_device	dummy_dev;
	struct napi_struct	napi;
	struct device *dev;

#ifdef HIF_NAPI_STATS
	unsigned int napi_counters[NAPI_MAX_COUNT];
#endif
	struct tasklet_struct	tx_cleanup_tasklet;
};

void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int
			q_no, void *data, u32 len, unsigned int flags);
int hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no,
		 void *data, unsigned int len);
void __hif_tx_done_process(struct pfe_hif *hif, int count);
void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int
				data2);
int pfe_hif_init(struct pfe *pfe);
void pfe_hif_exit(struct pfe *pfe);
void pfe_hif_rx_idle(struct pfe_hif *hif);
static inline void hif_tx_done_process(struct pfe_hif *hif, int count)
{
	spin_lock_bh(&hif->tx_lock);
	__hif_tx_done_process(hif, count);
	spin_unlock_bh(&hif->tx_lock);
}

static inline void hif_tx_lock(struct pfe_hif *hif)
{
	spin_lock_bh(&hif->tx_lock);
}

static inline void hif_tx_unlock(struct pfe_hif *hif)
{
	spin_unlock_bh(&hif->tx_lock);
}

static inline int __hif_tx_avail(struct pfe_hif *hif)
{
	return hif->txavail;
}

#define __memcpy8(dst, src)		memcpy(dst, src, 8)
#define __memcpy12(dst, src)		memcpy(dst, src, 12)
#define __memcpy(dst, src, len)		memcpy(dst, src, len)

#endif /* _PFE_HIF_H_ */