xref: /linux/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h (revision 04e10e2164fcfa05e14eff3c2757a5097f11d258)
1f7917c00SJeff Kirsher /*
2f7917c00SJeff Kirsher  * This file is part of the Chelsio T4 Ethernet driver for Linux.
3f7917c00SJeff Kirsher  *
4ce100b8bSAnish Bhatt  * Copyright (c) 2003-2014 Chelsio Communications, Inc. All rights reserved.
5f7917c00SJeff Kirsher  *
6f7917c00SJeff Kirsher  * This software is available to you under a choice of one of two
7f7917c00SJeff Kirsher  * licenses.  You may choose to be licensed under the terms of the GNU
8f7917c00SJeff Kirsher  * General Public License (GPL) Version 2, available from the file
9f7917c00SJeff Kirsher  * COPYING in the main directory of this source tree, or the
10f7917c00SJeff Kirsher  * OpenIB.org BSD license below:
11f7917c00SJeff Kirsher  *
12f7917c00SJeff Kirsher  *     Redistribution and use in source and binary forms, with or
13f7917c00SJeff Kirsher  *     without modification, are permitted provided that the following
14f7917c00SJeff Kirsher  *     conditions are met:
15f7917c00SJeff Kirsher  *
16f7917c00SJeff Kirsher  *      - Redistributions of source code must retain the above
17f7917c00SJeff Kirsher  *        copyright notice, this list of conditions and the following
18f7917c00SJeff Kirsher  *        disclaimer.
19f7917c00SJeff Kirsher  *
20f7917c00SJeff Kirsher  *      - Redistributions in binary form must reproduce the above
21f7917c00SJeff Kirsher  *        copyright notice, this list of conditions and the following
22f7917c00SJeff Kirsher  *        disclaimer in the documentation and/or other materials
23f7917c00SJeff Kirsher  *        provided with the distribution.
24f7917c00SJeff Kirsher  *
25f7917c00SJeff Kirsher  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26f7917c00SJeff Kirsher  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27f7917c00SJeff Kirsher  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28f7917c00SJeff Kirsher  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29f7917c00SJeff Kirsher  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30f7917c00SJeff Kirsher  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31f7917c00SJeff Kirsher  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32f7917c00SJeff Kirsher  * SOFTWARE.
33f7917c00SJeff Kirsher  */
34f7917c00SJeff Kirsher 
35f7917c00SJeff Kirsher #ifndef __CXGB4_OFLD_H
36f7917c00SJeff Kirsher #define __CXGB4_OFLD_H
37f7917c00SJeff Kirsher 
38f7917c00SJeff Kirsher #include <linux/cache.h>
39f7917c00SJeff Kirsher #include <linux/spinlock.h>
40f7917c00SJeff Kirsher #include <linux/skbuff.h>
41793dad94SVipul Pandya #include <linux/inetdevice.h>
42f7917c00SJeff Kirsher #include <linux/atomic.h>
43f7917c00SJeff Kirsher 
44f7917c00SJeff Kirsher /* CPL message priority levels */
45f7917c00SJeff Kirsher enum {
46f7917c00SJeff Kirsher 	CPL_PRIORITY_DATA     = 0,  /* data messages */
47f7917c00SJeff Kirsher 	CPL_PRIORITY_SETUP    = 1,  /* connection setup messages */
48f7917c00SJeff Kirsher 	CPL_PRIORITY_TEARDOWN = 0,  /* connection teardown messages */
49f7917c00SJeff Kirsher 	CPL_PRIORITY_LISTEN   = 1,  /* listen start/stop messages */
50f7917c00SJeff Kirsher 	CPL_PRIORITY_ACK      = 1,  /* RX ACK messages */
51f7917c00SJeff Kirsher 	CPL_PRIORITY_CONTROL  = 1   /* control messages */
52f7917c00SJeff Kirsher };
53f7917c00SJeff Kirsher 
54f7917c00SJeff Kirsher #define INIT_TP_WR(w, tid) do { \
55f7917c00SJeff Kirsher 	(w)->wr.wr_hi = htonl(FW_WR_OP(FW_TP_WR) | \
56f7917c00SJeff Kirsher 			      FW_WR_IMMDLEN(sizeof(*w) - sizeof(w->wr))); \
57f7917c00SJeff Kirsher 	(w)->wr.wr_mid = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*w), 16)) | \
58f7917c00SJeff Kirsher 			       FW_WR_FLOWID(tid)); \
59f7917c00SJeff Kirsher 	(w)->wr.wr_lo = cpu_to_be64(0); \
60f7917c00SJeff Kirsher } while (0)
61f7917c00SJeff Kirsher 
62f7917c00SJeff Kirsher #define INIT_TP_WR_CPL(w, cpl, tid) do { \
63f7917c00SJeff Kirsher 	INIT_TP_WR(w, tid); \
64f7917c00SJeff Kirsher 	OPCODE_TID(w) = htonl(MK_OPCODE_TID(cpl, tid)); \
65f7917c00SJeff Kirsher } while (0)
66f7917c00SJeff Kirsher 
67f7917c00SJeff Kirsher #define INIT_ULPTX_WR(w, wrlen, atomic, tid) do { \
68f7917c00SJeff Kirsher 	(w)->wr.wr_hi = htonl(FW_WR_OP(FW_ULPTX_WR) | FW_WR_ATOMIC(atomic)); \
69f7917c00SJeff Kirsher 	(w)->wr.wr_mid = htonl(FW_WR_LEN16(DIV_ROUND_UP(wrlen, 16)) | \
70f7917c00SJeff Kirsher 			       FW_WR_FLOWID(tid)); \
71f7917c00SJeff Kirsher 	(w)->wr.wr_lo = cpu_to_be64(0); \
72f7917c00SJeff Kirsher } while (0)
73f7917c00SJeff Kirsher 
74f7917c00SJeff Kirsher /* Special asynchronous notification message */
75f7917c00SJeff Kirsher #define CXGB4_MSG_AN ((void *)1)
76f7917c00SJeff Kirsher 
77f7917c00SJeff Kirsher struct serv_entry {
78f7917c00SJeff Kirsher 	void *data;
79f7917c00SJeff Kirsher };
80f7917c00SJeff Kirsher 
81f7917c00SJeff Kirsher union aopen_entry {
82f7917c00SJeff Kirsher 	void *data;
83f7917c00SJeff Kirsher 	union aopen_entry *next;
84f7917c00SJeff Kirsher };
85f7917c00SJeff Kirsher 
86f7917c00SJeff Kirsher /*
87f7917c00SJeff Kirsher  * Holds the size, base address, free list start, etc of the TID, server TID,
88f7917c00SJeff Kirsher  * and active-open TID tables.  The tables themselves are allocated dynamically.
89f7917c00SJeff Kirsher  */
90f7917c00SJeff Kirsher struct tid_info {
91f7917c00SJeff Kirsher 	void **tid_tab;
92f7917c00SJeff Kirsher 	unsigned int ntids;
93f7917c00SJeff Kirsher 
94f7917c00SJeff Kirsher 	struct serv_entry *stid_tab;
95f7917c00SJeff Kirsher 	unsigned long *stid_bmap;
96f7917c00SJeff Kirsher 	unsigned int nstids;
97f7917c00SJeff Kirsher 	unsigned int stid_base;
98f7917c00SJeff Kirsher 
99f7917c00SJeff Kirsher 	union aopen_entry *atid_tab;
100f7917c00SJeff Kirsher 	unsigned int natids;
101f2b7e78dSVipul Pandya 	unsigned int atid_base;
102f7917c00SJeff Kirsher 
103f2b7e78dSVipul Pandya 	struct filter_entry *ftid_tab;
104f7917c00SJeff Kirsher 	unsigned int nftids;
105f7917c00SJeff Kirsher 	unsigned int ftid_base;
106636f9d37SVipul Pandya 	unsigned int aftid_base;
107636f9d37SVipul Pandya 	unsigned int aftid_end;
1089a4da2cdSVipul Pandya 	/* Server filter region */
1099a4da2cdSVipul Pandya 	unsigned int sftid_base;
1109a4da2cdSVipul Pandya 	unsigned int nsftids;
111f7917c00SJeff Kirsher 
112f7917c00SJeff Kirsher 	spinlock_t atid_lock ____cacheline_aligned_in_smp;
113f7917c00SJeff Kirsher 	union aopen_entry *afree;
114f7917c00SJeff Kirsher 	unsigned int atids_in_use;
115f7917c00SJeff Kirsher 
116f7917c00SJeff Kirsher 	spinlock_t stid_lock;
117f7917c00SJeff Kirsher 	unsigned int stids_in_use;
118f7917c00SJeff Kirsher 
119f7917c00SJeff Kirsher 	atomic_t tids_in_use;
120f7917c00SJeff Kirsher };
121f7917c00SJeff Kirsher 
122f7917c00SJeff Kirsher static inline void *lookup_tid(const struct tid_info *t, unsigned int tid)
123f7917c00SJeff Kirsher {
124f7917c00SJeff Kirsher 	return tid < t->ntids ? t->tid_tab[tid] : NULL;
125f7917c00SJeff Kirsher }
126f7917c00SJeff Kirsher 
127f7917c00SJeff Kirsher static inline void *lookup_atid(const struct tid_info *t, unsigned int atid)
128f7917c00SJeff Kirsher {
129f7917c00SJeff Kirsher 	return atid < t->natids ? t->atid_tab[atid].data : NULL;
130f7917c00SJeff Kirsher }
131f7917c00SJeff Kirsher 
132f7917c00SJeff Kirsher static inline void *lookup_stid(const struct tid_info *t, unsigned int stid)
133f7917c00SJeff Kirsher {
134470c60c4SKumar Sanghvi 	/* Is it a server filter TID? */
135470c60c4SKumar Sanghvi 	if (t->nsftids && (stid >= t->sftid_base)) {
136470c60c4SKumar Sanghvi 		stid -= t->sftid_base;
137470c60c4SKumar Sanghvi 		stid += t->nstids;
138470c60c4SKumar Sanghvi 	} else {
139f7917c00SJeff Kirsher 		stid -= t->stid_base;
140470c60c4SKumar Sanghvi 	}
141470c60c4SKumar Sanghvi 
142dca4faebSVipul Pandya 	return stid < (t->nstids + t->nsftids) ? t->stid_tab[stid].data : NULL;
143f7917c00SJeff Kirsher }
144f7917c00SJeff Kirsher 
145f7917c00SJeff Kirsher static inline void cxgb4_insert_tid(struct tid_info *t, void *data,
146f7917c00SJeff Kirsher 				    unsigned int tid)
147f7917c00SJeff Kirsher {
148f7917c00SJeff Kirsher 	t->tid_tab[tid] = data;
149f7917c00SJeff Kirsher 	atomic_inc(&t->tids_in_use);
150f7917c00SJeff Kirsher }
151f7917c00SJeff Kirsher 
152f7917c00SJeff Kirsher int cxgb4_alloc_atid(struct tid_info *t, void *data);
153f7917c00SJeff Kirsher int cxgb4_alloc_stid(struct tid_info *t, int family, void *data);
154dca4faebSVipul Pandya int cxgb4_alloc_sftid(struct tid_info *t, int family, void *data);
155f7917c00SJeff Kirsher void cxgb4_free_atid(struct tid_info *t, unsigned int atid);
156f7917c00SJeff Kirsher void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family);
157f7917c00SJeff Kirsher void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid);
158f7917c00SJeff Kirsher 
159f7917c00SJeff Kirsher struct in6_addr;
160f7917c00SJeff Kirsher 
161f7917c00SJeff Kirsher int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
162793dad94SVipul Pandya 			__be32 sip, __be16 sport, __be16 vlan,
163793dad94SVipul Pandya 			unsigned int queue);
16480f40c1fSVipul Pandya int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
16580f40c1fSVipul Pandya 			 const struct in6_addr *sip, __be16 sport,
16680f40c1fSVipul Pandya 			 unsigned int queue);
16780f40c1fSVipul Pandya int cxgb4_remove_server(const struct net_device *dev, unsigned int stid,
16880f40c1fSVipul Pandya 			unsigned int queue, bool ipv6);
169dca4faebSVipul Pandya int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid,
170793dad94SVipul Pandya 			       __be32 sip, __be16 sport, __be16 vlan,
171793dad94SVipul Pandya 			       unsigned int queue,
172793dad94SVipul Pandya 			       unsigned char port, unsigned char mask);
173dca4faebSVipul Pandya int cxgb4_remove_server_filter(const struct net_device *dev, unsigned int stid,
174dca4faebSVipul Pandya 			       unsigned int queue, bool ipv6);
175f7917c00SJeff Kirsher static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue)
176f7917c00SJeff Kirsher {
177f7917c00SJeff Kirsher 	skb_set_queue_mapping(skb, (queue << 1) | prio);
178f7917c00SJeff Kirsher }
179f7917c00SJeff Kirsher 
180f7917c00SJeff Kirsher enum cxgb4_uld {
181f7917c00SJeff Kirsher 	CXGB4_ULD_RDMA,
182f7917c00SJeff Kirsher 	CXGB4_ULD_ISCSI,
183f7917c00SJeff Kirsher 	CXGB4_ULD_MAX
184f7917c00SJeff Kirsher };
185f7917c00SJeff Kirsher 
186f7917c00SJeff Kirsher enum cxgb4_state {
187f7917c00SJeff Kirsher 	CXGB4_STATE_UP,
188f7917c00SJeff Kirsher 	CXGB4_STATE_START_RECOVERY,
189f7917c00SJeff Kirsher 	CXGB4_STATE_DOWN,
190f7917c00SJeff Kirsher 	CXGB4_STATE_DETACH
191f7917c00SJeff Kirsher };
192f7917c00SJeff Kirsher 
193881806bcSVipul Pandya enum cxgb4_control {
194881806bcSVipul Pandya 	CXGB4_CONTROL_DB_FULL,
195881806bcSVipul Pandya 	CXGB4_CONTROL_DB_EMPTY,
196881806bcSVipul Pandya 	CXGB4_CONTROL_DB_DROP,
197881806bcSVipul Pandya };
198881806bcSVipul Pandya 
199f7917c00SJeff Kirsher struct pci_dev;
200f7917c00SJeff Kirsher struct l2t_data;
201f7917c00SJeff Kirsher struct net_device;
202f7917c00SJeff Kirsher struct pkt_gl;
203f7917c00SJeff Kirsher struct tp_tcp_stats;
204f7917c00SJeff Kirsher 
205f7917c00SJeff Kirsher struct cxgb4_range {
206f7917c00SJeff Kirsher 	unsigned int start;
207f7917c00SJeff Kirsher 	unsigned int size;
208f7917c00SJeff Kirsher };
209f7917c00SJeff Kirsher 
210f7917c00SJeff Kirsher struct cxgb4_virt_res {                      /* virtualized HW resources */
211f7917c00SJeff Kirsher 	struct cxgb4_range ddp;
212f7917c00SJeff Kirsher 	struct cxgb4_range iscsi;
213f7917c00SJeff Kirsher 	struct cxgb4_range stag;
214f7917c00SJeff Kirsher 	struct cxgb4_range rq;
215f7917c00SJeff Kirsher 	struct cxgb4_range pbl;
216f7917c00SJeff Kirsher 	struct cxgb4_range qp;
217f7917c00SJeff Kirsher 	struct cxgb4_range cq;
218f7917c00SJeff Kirsher 	struct cxgb4_range ocq;
219f7917c00SJeff Kirsher };
220f7917c00SJeff Kirsher 
221f7917c00SJeff Kirsher #define OCQ_WIN_OFFSET(pdev, vres) \
222f7917c00SJeff Kirsher 	(pci_resource_len((pdev), 2) - roundup_pow_of_two((vres)->ocq.size))
223f7917c00SJeff Kirsher 
224f7917c00SJeff Kirsher /*
225f7917c00SJeff Kirsher  * Block of information the LLD provides to ULDs attaching to a device.
226f7917c00SJeff Kirsher  */
227f7917c00SJeff Kirsher struct cxgb4_lld_info {
228f7917c00SJeff Kirsher 	struct pci_dev *pdev;                /* associated PCI device */
229f7917c00SJeff Kirsher 	struct l2t_data *l2t;                /* L2 table */
230f7917c00SJeff Kirsher 	struct tid_info *tids;               /* TID table */
231f7917c00SJeff Kirsher 	struct net_device **ports;           /* device ports */
232f7917c00SJeff Kirsher 	const struct cxgb4_virt_res *vr;     /* assorted HW resources */
233f7917c00SJeff Kirsher 	const unsigned short *mtus;          /* MTU table */
234f7917c00SJeff Kirsher 	const unsigned short *rxq_ids;       /* the ULD's Rx queue ids */
235cf38be6dSHariprasad Shenai 	const unsigned short *ciq_ids;       /* the ULD's concentrator IQ ids */
236f7917c00SJeff Kirsher 	unsigned short nrxq;                 /* # of Rx queues */
237f7917c00SJeff Kirsher 	unsigned short ntxq;                 /* # of Tx queues */
238cf38be6dSHariprasad Shenai 	unsigned short nciq;		     /* # of concentrator IQ */
239f7917c00SJeff Kirsher 	unsigned char nchan:4;               /* # of channels */
240f7917c00SJeff Kirsher 	unsigned char nports:4;              /* # of ports */
241f7917c00SJeff Kirsher 	unsigned char wr_cred;               /* WR 16-byte credits */
242f7917c00SJeff Kirsher 	unsigned char adapter_type;          /* type of adapter */
243f7917c00SJeff Kirsher 	unsigned char fw_api_ver;            /* FW API version */
244f7917c00SJeff Kirsher 	unsigned int fw_vers;                /* FW version */
245f7917c00SJeff Kirsher 	unsigned int iscsi_iolen;            /* iSCSI max I/O length */
246f7917c00SJeff Kirsher 	unsigned short udb_density;          /* # of user DB/page */
247f7917c00SJeff Kirsher 	unsigned short ucq_density;          /* # of user CQs/page */
248dca4faebSVipul Pandya 	unsigned short filt_mode;            /* filter optional components */
249dca4faebSVipul Pandya 	unsigned short tx_modq[NCHAN];       /* maps each tx channel to a */
250dca4faebSVipul Pandya 					     /* scheduler queue */
251f7917c00SJeff Kirsher 	void __iomem *gts_reg;               /* address of GTS register */
252f7917c00SJeff Kirsher 	void __iomem *db_reg;                /* address of kernel doorbell */
2533069ee9bSVipul Pandya 	int dbfifo_int_thresh;		     /* doorbell fifo int threshold */
254*04e10e21SHariprasad Shenai 	unsigned int sge_ingpadboundary;     /* SGE ingress padding boundary */
255*04e10e21SHariprasad Shenai 	unsigned int sge_egrstatuspagesize;  /* SGE egress status page size */
256dca4faebSVipul Pandya 	unsigned int sge_pktshift;           /* Padding between CPL and */
257dca4faebSVipul Pandya 					     /*	packet data */
25835b1de55SHariprasad Shenai 	unsigned int pf;		     /* Physical Function we're using */
259dca4faebSVipul Pandya 	bool enable_fw_ofld_conn;            /* Enable connection through fw */
260dca4faebSVipul Pandya 					     /* WR */
2611ac0f095SKumar Sanghvi 	bool ulptx_memwrite_dsgl;            /* use of T5 DSGL allowed */
262f7917c00SJeff Kirsher };
263f7917c00SJeff Kirsher 
264f7917c00SJeff Kirsher struct cxgb4_uld_info {
265f7917c00SJeff Kirsher 	const char *name;
266f7917c00SJeff Kirsher 	void *(*add)(const struct cxgb4_lld_info *p);
267f7917c00SJeff Kirsher 	int (*rx_handler)(void *handle, const __be64 *rsp,
268f7917c00SJeff Kirsher 			  const struct pkt_gl *gl);
269f7917c00SJeff Kirsher 	int (*state_change)(void *handle, enum cxgb4_state new_state);
2703069ee9bSVipul Pandya 	int (*control)(void *handle, enum cxgb4_control control, ...);
271f7917c00SJeff Kirsher };
272f7917c00SJeff Kirsher 
273f7917c00SJeff Kirsher int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p);
274f7917c00SJeff Kirsher int cxgb4_unregister_uld(enum cxgb4_uld type);
275f7917c00SJeff Kirsher int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb);
276881806bcSVipul Pandya unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo);
277f7917c00SJeff Kirsher unsigned int cxgb4_port_chan(const struct net_device *dev);
278f7917c00SJeff Kirsher unsigned int cxgb4_port_viid(const struct net_device *dev);
279f7917c00SJeff Kirsher unsigned int cxgb4_port_idx(const struct net_device *dev);
280f7917c00SJeff Kirsher unsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu,
281f7917c00SJeff Kirsher 			    unsigned int *idx);
28292e7ae71SHariprasad Shenai unsigned int cxgb4_best_aligned_mtu(const unsigned short *mtus,
28392e7ae71SHariprasad Shenai 				    unsigned short header_size,
28492e7ae71SHariprasad Shenai 				    unsigned short data_size_max,
28592e7ae71SHariprasad Shenai 				    unsigned short data_size_align,
28692e7ae71SHariprasad Shenai 				    unsigned int *mtu_idxp);
287f7917c00SJeff Kirsher void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4,
288f7917c00SJeff Kirsher 			 struct tp_tcp_stats *v6);
289f7917c00SJeff Kirsher void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask,
290f7917c00SJeff Kirsher 		      const unsigned int *pgsz_order);
291f7917c00SJeff Kirsher struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
292f7917c00SJeff Kirsher 				   unsigned int skb_len, unsigned int pull_len);
2933069ee9bSVipul Pandya int cxgb4_sync_txq_pidx(struct net_device *dev, u16 qid, u16 pidx, u16 size);
2943069ee9bSVipul Pandya int cxgb4_flush_eq_cache(struct net_device *dev);
2953cbdb928SVipul Pandya void cxgb4_disable_db_coalescing(struct net_device *dev);
2963cbdb928SVipul Pandya void cxgb4_enable_db_coalescing(struct net_device *dev);
2973cbdb928SVipul Pandya 
298f7917c00SJeff Kirsher #endif  /* !__CXGB4_OFLD_H */
299