summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/cavium/liquidio/octeon_iq.h
blob: 81c98768294174a44d7150d4a6ee08938a90f5f3 (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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
/**********************************************************************
 * Author: Cavium, Inc.
 *
 * Contact: support@cavium.com
 *          Please include "LiquidIO" in the subject.
 *
 * Copyright (c) 2003-2016 Cavium, Inc.
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, Version 2, as
 * published by the Free Software Foundation.
 *
 * This file is distributed in the hope that it will be useful, but
 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
 * NONINFRINGEMENT.  See the GNU General Public License for more details.
 ***********************************************************************/
/*!  \file  octeon_iq.h
 *   \brief Host Driver: Implementation of Octeon input queues. "Input" is
 *   with respect to the Octeon device on the NIC. From this driver's
 *   point of view they are egress queues.
 */

#ifndef __OCTEON_IQ_H__
#define  __OCTEON_IQ_H__

#define IQ_STATUS_RUNNING   1

#define IQ_SEND_OK          0
#define IQ_SEND_STOP        1
#define IQ_SEND_FAILED     -1

/*-------------------------  INSTRUCTION QUEUE --------------------------*/

/* \cond */

#define REQTYPE_NONE                 0
#define REQTYPE_NORESP_NET           1
#define REQTYPE_NORESP_NET_SG        2
#define REQTYPE_RESP_NET             3
#define REQTYPE_RESP_NET_SG          4
#define REQTYPE_SOFT_COMMAND         5
#define REQTYPE_LAST                 5

struct octeon_request_list {
	u32 reqtype;
	void *buf;
};

/* \endcond */

/** Input Queue statistics. Each input queue has four stats fields. */
struct oct_iq_stats {
	u64 instr_posted; /**< Instructions posted to this queue. */
	u64 instr_processed; /**< Instructions processed in this queue. */
	u64 instr_dropped; /**< Instructions that could not be processed */
	u64 bytes_sent;  /**< Bytes sent through this queue. */
	u64 sgentry_sent;/**< Gather entries sent through this queue. */
	u64 tx_done;/**< Num of packets sent to network. */
	u64 tx_iq_busy;/**< Numof times this iq was found to be full. */
	u64 tx_dropped;/**< Numof pkts dropped dueto xmitpath errors. */
	u64 tx_tot_bytes;/**< Total count of bytes sento to network. */
	u64 tx_gso;  /* count of tso */
	u64 tx_vxlan; /* tunnel */
	u64 tx_dmamap_fail;
	u64 tx_restart;
};

#define OCT_IQ_STATS_SIZE   (sizeof(struct oct_iq_stats))

/** The instruction (input) queue.
 *  The input queue is used to post raw (instruction) mode data or packet
 *  data to Octeon device from the host. Each input queue (upto 4) for
 *  a Octeon device has one such structure to represent it.
 */
struct octeon_instr_queue {
	struct octeon_device *oct_dev;

	/** A spinlock to protect access to the input ring.  */
	spinlock_t lock;

	/** A spinlock to protect while posting on the ring.  */
	spinlock_t post_lock;

	u32 pkt_in_done;

	/** A spinlock to protect access to the input ring.*/
	spinlock_t iq_flush_running_lock;

	/** Flag that indicates if the queue uses 64 byte commands. */
	u32 iqcmd_64B:1;

	/** Queue info. */
	union oct_txpciq txpciq;

	u32 rsvd:17;

	/* Controls whether extra flushing of IQ is done on Tx */
	u32 do_auto_flush:1;

	u32 status:8;

	/** Maximum no. of instructions in this queue. */
	u32 max_count;

	/** Index in input ring where the driver should write the next packet */
	u32 host_write_index;

	/** Index in input ring where Octeon is expected to read the next
	 * packet.
	 */
	u32 octeon_read_index;

	/** This index aids in finding the window in the queue where Octeon
	 *  has read the commands.
	 */
	u32 flush_index;

	/** This field keeps track of the instructions pending in this queue. */
	atomic_t instr_pending;

	u32 reset_instr_cnt;

	/** Pointer to the Virtual Base addr of the input ring. */
	u8 *base_addr;

	struct octeon_request_list *request_list;

	/** Octeon doorbell register for the ring. */
	void __iomem *doorbell_reg;

	/** Octeon instruction count register for this ring. */
	void __iomem *inst_cnt_reg;

	/** Number of instructions pending to be posted to Octeon. */
	u32 fill_cnt;

	/** The max. number of instructions that can be held pending by the
	 * driver.
	 */
	u32 fill_threshold;

	/** The last time that the doorbell was rung. */
	u64 last_db_time;

	/** The doorbell timeout. If the doorbell was not rung for this time and
	 * fill_cnt is non-zero, ring the doorbell again.
	 */
	u32 db_timeout;

	/** Statistics for this input queue. */
	struct oct_iq_stats stats;

	/** DMA mapped base address of the input descriptor ring. */
	dma_addr_t base_addr_dma;

	/** Application context */
	void *app_ctx;

	/* network stack queue index */
	int q_index;

	/*os ifidx associated with this queue */
	int ifidx;

};

/*----------------------  INSTRUCTION FORMAT ----------------------------*/

/** 32-byte instruction format.
 *  Format of instruction for a 32-byte mode input queue.
 */
struct octeon_instr_32B {
	/** Pointer where the input data is available. */
	u64 dptr;

	/** Instruction Header.  */
	u64 ih;

	/** Pointer where the response for a RAW mode packet will be written
	 * by Octeon.
	 */
	u64 rptr;

	/** Input Request Header. Additional info about the input. */
	u64 irh;

};

#define OCT_32B_INSTR_SIZE     (sizeof(struct octeon_instr_32B))

/** 64-byte instruction format.
 *  Format of instruction for a 64-byte mode input queue.
 */
struct octeon_instr2_64B {
	/** Pointer where the input data is available. */
	u64 dptr;

	/** Instruction Header. */
	u64 ih2;

	/** Input Request Header. */
	u64 irh;

	/** opcode/subcode specific parameters */
	u64 ossp[2];

	/** Return Data Parameters */
	u64 rdp;

	/** Pointer where the response for a RAW mode packet will be written
	 * by Octeon.
	 */
	u64 rptr;

	u64 reserved;
};

struct octeon_instr3_64B {
	/** Pointer where the input data is available. */
	u64 dptr;

	/** Instruction Header. */
	u64 ih3;

	/** Instruction Header. */
	u64 pki_ih3;

	/** Input Request Header. */
	u64 irh;

	/** opcode/subcode specific parameters */
	u64 ossp[2];

	/** Return Data Parameters */
	u64 rdp;

	/** Pointer where the response for a RAW mode packet will be written
	 * by Octeon.
	 */
	u64 rptr;

};

union octeon_instr_64B {
	struct octeon_instr2_64B cmd2;
	struct octeon_instr3_64B cmd3;
};

#define OCT_64B_INSTR_SIZE     (sizeof(union octeon_instr_64B))

/** The size of each buffer in soft command buffer pool
 */
#define  SOFT_COMMAND_BUFFER_SIZE	2048

struct octeon_soft_command {
	/** Soft command buffer info. */
	struct list_head node;
	u64 dma_addr;
	u32 size;

	/** Command and return status */
	union octeon_instr_64B cmd;

#define COMPLETION_WORD_INIT    0xffffffffffffffffULL
	u64 *status_word;

	/** Data buffer info */
	void *virtdptr;
	u64 dmadptr;
	u32 datasize;

	/** Return buffer info */
	void *virtrptr;
	u64 dmarptr;
	u32 rdatasize;

	/** Context buffer info */
	void *ctxptr;
	u32  ctxsize;

	/** Time out and callback */
	size_t wait_time;
	size_t timeout;
	u32 iq_no;
	void (*callback)(struct octeon_device *, u32, void *);
	void *callback_arg;
};

/** Maximum number of buffers to allocate into soft command buffer pool
 */
#define  MAX_SOFT_COMMAND_BUFFERS	256

/** Head of a soft command buffer pool.
 */
struct octeon_sc_buffer_pool {
	/** List structure to add delete pending entries to */
	struct list_head head;

	/** A lock for this response list */
	spinlock_t lock;

	atomic_t alloc_buf_count;
};

#define INCR_INSTRQUEUE_PKT_COUNT(octeon_dev_ptr, iq_no, field, count)  \
		(((octeon_dev_ptr)->instr_queue[iq_no]->stats.field) += count)

int octeon_setup_sc_buffer_pool(struct octeon_device *oct);
int octeon_free_sc_buffer_pool(struct octeon_device *oct);
struct octeon_soft_command *
	octeon_alloc_soft_command(struct octeon_device *oct,
				  u32 datasize, u32 rdatasize,
				  u32 ctxsize);
void octeon_free_soft_command(struct octeon_device *oct,
			      struct octeon_soft_command *sc);

/**
 *  octeon_init_instr_queue()
 *  @param octeon_dev      - pointer to the octeon device structure.
 *  @param txpciq          - queue to be initialized (0 <= q_no <= 3).
 *
 *  Called at driver init time for each input queue. iq_conf has the
 *  configuration parameters for the queue.
 *
 *  @return  Success: 0   Failure: 1
 */
int octeon_init_instr_queue(struct octeon_device *octeon_dev,
			    union oct_txpciq txpciq,
			    u32 num_descs);

/**
 *  octeon_delete_instr_queue()
 *  @param octeon_dev      - pointer to the octeon device structure.
 *  @param iq_no           - queue to be deleted (0 <= q_no <= 3).
 *
 *  Called at driver unload time for each input queue. Deletes all
 *  allocated resources for the input queue.
 *
 *  @return  Success: 0   Failure: 1
 */
int octeon_delete_instr_queue(struct octeon_device *octeon_dev, u32 iq_no);

int lio_wait_for_instr_fetch(struct octeon_device *oct);

void
octeon_ring_doorbell_locked(struct octeon_device *oct, u32 iq_no);

int
octeon_register_reqtype_free_fn(struct octeon_device *oct, int reqtype,
				void (*fn)(void *));

int
lio_process_iq_request_list(struct octeon_device *oct,
			    struct octeon_instr_queue *iq, u32 napi_budget);

int octeon_send_command(struct octeon_device *oct, u32 iq_no,
			u32 force_db, void *cmd, void *buf,
			u32 datasize, u32 reqtype);

void octeon_prepare_soft_command(struct octeon_device *oct,
				 struct octeon_soft_command *sc,
				 u8 opcode, u8 subcode,
				 u32 irh_ossp, u64 ossp0,
				 u64 ossp1);

int octeon_send_soft_command(struct octeon_device *oct,
			     struct octeon_soft_command *sc);

int octeon_setup_iq(struct octeon_device *oct, int ifidx,
		    int q_index, union oct_txpciq iq_no, u32 num_descs,
		    void *app_ctx);
int
octeon_flush_iq(struct octeon_device *oct, struct octeon_instr_queue *iq,
		u32 napi_budget);
#endif				/* __OCTEON_IQ_H__ */