xref: /linux/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h (revision 881806bc155c0d5d78196c8bfae0ea2e76ae7386)
1f7917c00SJeff Kirsher /*
2f7917c00SJeff Kirsher  * This file is part of the Chelsio T4 Ethernet driver for Linux.
3f7917c00SJeff Kirsher  *
4f7917c00SJeff Kirsher  * Copyright (c) 2003-2010 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>
41f7917c00SJeff Kirsher #include <linux/atomic.h>
42f7917c00SJeff Kirsher 
43f7917c00SJeff Kirsher /* CPL message priority levels */
44f7917c00SJeff Kirsher enum {
45f7917c00SJeff Kirsher 	CPL_PRIORITY_DATA     = 0,  /* data messages */
46f7917c00SJeff Kirsher 	CPL_PRIORITY_SETUP    = 1,  /* connection setup messages */
47f7917c00SJeff Kirsher 	CPL_PRIORITY_TEARDOWN = 0,  /* connection teardown messages */
48f7917c00SJeff Kirsher 	CPL_PRIORITY_LISTEN   = 1,  /* listen start/stop messages */
49f7917c00SJeff Kirsher 	CPL_PRIORITY_ACK      = 1,  /* RX ACK messages */
50f7917c00SJeff Kirsher 	CPL_PRIORITY_CONTROL  = 1   /* control messages */
51f7917c00SJeff Kirsher };
52f7917c00SJeff Kirsher 
53f7917c00SJeff Kirsher #define INIT_TP_WR(w, tid) do { \
54f7917c00SJeff Kirsher 	(w)->wr.wr_hi = htonl(FW_WR_OP(FW_TP_WR) | \
55f7917c00SJeff Kirsher 			      FW_WR_IMMDLEN(sizeof(*w) - sizeof(w->wr))); \
56f7917c00SJeff Kirsher 	(w)->wr.wr_mid = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*w), 16)) | \
57f7917c00SJeff Kirsher 			       FW_WR_FLOWID(tid)); \
58f7917c00SJeff Kirsher 	(w)->wr.wr_lo = cpu_to_be64(0); \
59f7917c00SJeff Kirsher } while (0)
60f7917c00SJeff Kirsher 
61f7917c00SJeff Kirsher #define INIT_TP_WR_CPL(w, cpl, tid) do { \
62f7917c00SJeff Kirsher 	INIT_TP_WR(w, tid); \
63f7917c00SJeff Kirsher 	OPCODE_TID(w) = htonl(MK_OPCODE_TID(cpl, tid)); \
64f7917c00SJeff Kirsher } while (0)
65f7917c00SJeff Kirsher 
66f7917c00SJeff Kirsher #define INIT_ULPTX_WR(w, wrlen, atomic, tid) do { \
67f7917c00SJeff Kirsher 	(w)->wr.wr_hi = htonl(FW_WR_OP(FW_ULPTX_WR) | FW_WR_ATOMIC(atomic)); \
68f7917c00SJeff Kirsher 	(w)->wr.wr_mid = htonl(FW_WR_LEN16(DIV_ROUND_UP(wrlen, 16)) | \
69f7917c00SJeff Kirsher 			       FW_WR_FLOWID(tid)); \
70f7917c00SJeff Kirsher 	(w)->wr.wr_lo = cpu_to_be64(0); \
71f7917c00SJeff Kirsher } while (0)
72f7917c00SJeff Kirsher 
73f7917c00SJeff Kirsher /* Special asynchronous notification message */
74f7917c00SJeff Kirsher #define CXGB4_MSG_AN ((void *)1)
75f7917c00SJeff Kirsher 
76f7917c00SJeff Kirsher struct serv_entry {
77f7917c00SJeff Kirsher 	void *data;
78f7917c00SJeff Kirsher };
79f7917c00SJeff Kirsher 
80f7917c00SJeff Kirsher union aopen_entry {
81f7917c00SJeff Kirsher 	void *data;
82f7917c00SJeff Kirsher 	union aopen_entry *next;
83f7917c00SJeff Kirsher };
84f7917c00SJeff Kirsher 
85f7917c00SJeff Kirsher /*
86f7917c00SJeff Kirsher  * Holds the size, base address, free list start, etc of the TID, server TID,
87f7917c00SJeff Kirsher  * and active-open TID tables.  The tables themselves are allocated dynamically.
88f7917c00SJeff Kirsher  */
89f7917c00SJeff Kirsher struct tid_info {
90f7917c00SJeff Kirsher 	void **tid_tab;
91f7917c00SJeff Kirsher 	unsigned int ntids;
92f7917c00SJeff Kirsher 
93f7917c00SJeff Kirsher 	struct serv_entry *stid_tab;
94f7917c00SJeff Kirsher 	unsigned long *stid_bmap;
95f7917c00SJeff Kirsher 	unsigned int nstids;
96f7917c00SJeff Kirsher 	unsigned int stid_base;
97f7917c00SJeff Kirsher 
98f7917c00SJeff Kirsher 	union aopen_entry *atid_tab;
99f7917c00SJeff Kirsher 	unsigned int natids;
100f7917c00SJeff Kirsher 
101f7917c00SJeff Kirsher 	unsigned int nftids;
102f7917c00SJeff Kirsher 	unsigned int ftid_base;
103f7917c00SJeff Kirsher 
104f7917c00SJeff Kirsher 	spinlock_t atid_lock ____cacheline_aligned_in_smp;
105f7917c00SJeff Kirsher 	union aopen_entry *afree;
106f7917c00SJeff Kirsher 	unsigned int atids_in_use;
107f7917c00SJeff Kirsher 
108f7917c00SJeff Kirsher 	spinlock_t stid_lock;
109f7917c00SJeff Kirsher 	unsigned int stids_in_use;
110f7917c00SJeff Kirsher 
111f7917c00SJeff Kirsher 	atomic_t tids_in_use;
112f7917c00SJeff Kirsher };
113f7917c00SJeff Kirsher 
114f7917c00SJeff Kirsher static inline void *lookup_tid(const struct tid_info *t, unsigned int tid)
115f7917c00SJeff Kirsher {
116f7917c00SJeff Kirsher 	return tid < t->ntids ? t->tid_tab[tid] : NULL;
117f7917c00SJeff Kirsher }
118f7917c00SJeff Kirsher 
119f7917c00SJeff Kirsher static inline void *lookup_atid(const struct tid_info *t, unsigned int atid)
120f7917c00SJeff Kirsher {
121f7917c00SJeff Kirsher 	return atid < t->natids ? t->atid_tab[atid].data : NULL;
122f7917c00SJeff Kirsher }
123f7917c00SJeff Kirsher 
124f7917c00SJeff Kirsher static inline void *lookup_stid(const struct tid_info *t, unsigned int stid)
125f7917c00SJeff Kirsher {
126f7917c00SJeff Kirsher 	stid -= t->stid_base;
127f7917c00SJeff Kirsher 	return stid < t->nstids ? t->stid_tab[stid].data : NULL;
128f7917c00SJeff Kirsher }
129f7917c00SJeff Kirsher 
130f7917c00SJeff Kirsher static inline void cxgb4_insert_tid(struct tid_info *t, void *data,
131f7917c00SJeff Kirsher 				    unsigned int tid)
132f7917c00SJeff Kirsher {
133f7917c00SJeff Kirsher 	t->tid_tab[tid] = data;
134f7917c00SJeff Kirsher 	atomic_inc(&t->tids_in_use);
135f7917c00SJeff Kirsher }
136f7917c00SJeff Kirsher 
137f7917c00SJeff Kirsher int cxgb4_alloc_atid(struct tid_info *t, void *data);
138f7917c00SJeff Kirsher int cxgb4_alloc_stid(struct tid_info *t, int family, void *data);
139f7917c00SJeff Kirsher void cxgb4_free_atid(struct tid_info *t, unsigned int atid);
140f7917c00SJeff Kirsher void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family);
141f7917c00SJeff Kirsher void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid);
142f7917c00SJeff Kirsher 
143f7917c00SJeff Kirsher struct in6_addr;
144f7917c00SJeff Kirsher 
145f7917c00SJeff Kirsher int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
146f7917c00SJeff Kirsher 			__be32 sip, __be16 sport, unsigned int queue);
147f7917c00SJeff Kirsher 
148f7917c00SJeff Kirsher static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue)
149f7917c00SJeff Kirsher {
150f7917c00SJeff Kirsher 	skb_set_queue_mapping(skb, (queue << 1) | prio);
151f7917c00SJeff Kirsher }
152f7917c00SJeff Kirsher 
153f7917c00SJeff Kirsher enum cxgb4_uld {
154f7917c00SJeff Kirsher 	CXGB4_ULD_RDMA,
155f7917c00SJeff Kirsher 	CXGB4_ULD_ISCSI,
156f7917c00SJeff Kirsher 	CXGB4_ULD_MAX
157f7917c00SJeff Kirsher };
158f7917c00SJeff Kirsher 
159f7917c00SJeff Kirsher enum cxgb4_state {
160f7917c00SJeff Kirsher 	CXGB4_STATE_UP,
161f7917c00SJeff Kirsher 	CXGB4_STATE_START_RECOVERY,
162f7917c00SJeff Kirsher 	CXGB4_STATE_DOWN,
163f7917c00SJeff Kirsher 	CXGB4_STATE_DETACH
164f7917c00SJeff Kirsher };
165f7917c00SJeff Kirsher 
166*881806bcSVipul Pandya enum cxgb4_control {
167*881806bcSVipul Pandya 	CXGB4_CONTROL_DB_FULL,
168*881806bcSVipul Pandya 	CXGB4_CONTROL_DB_EMPTY,
169*881806bcSVipul Pandya 	CXGB4_CONTROL_DB_DROP,
170*881806bcSVipul Pandya };
171*881806bcSVipul Pandya 
172f7917c00SJeff Kirsher struct pci_dev;
173f7917c00SJeff Kirsher struct l2t_data;
174f7917c00SJeff Kirsher struct net_device;
175f7917c00SJeff Kirsher struct pkt_gl;
176f7917c00SJeff Kirsher struct tp_tcp_stats;
177f7917c00SJeff Kirsher 
178f7917c00SJeff Kirsher struct cxgb4_range {
179f7917c00SJeff Kirsher 	unsigned int start;
180f7917c00SJeff Kirsher 	unsigned int size;
181f7917c00SJeff Kirsher };
182f7917c00SJeff Kirsher 
183f7917c00SJeff Kirsher struct cxgb4_virt_res {                      /* virtualized HW resources */
184f7917c00SJeff Kirsher 	struct cxgb4_range ddp;
185f7917c00SJeff Kirsher 	struct cxgb4_range iscsi;
186f7917c00SJeff Kirsher 	struct cxgb4_range stag;
187f7917c00SJeff Kirsher 	struct cxgb4_range rq;
188f7917c00SJeff Kirsher 	struct cxgb4_range pbl;
189f7917c00SJeff Kirsher 	struct cxgb4_range qp;
190f7917c00SJeff Kirsher 	struct cxgb4_range cq;
191f7917c00SJeff Kirsher 	struct cxgb4_range ocq;
192f7917c00SJeff Kirsher };
193f7917c00SJeff Kirsher 
194f7917c00SJeff Kirsher #define OCQ_WIN_OFFSET(pdev, vres) \
195f7917c00SJeff Kirsher 	(pci_resource_len((pdev), 2) - roundup_pow_of_two((vres)->ocq.size))
196f7917c00SJeff Kirsher 
197f7917c00SJeff Kirsher /*
198f7917c00SJeff Kirsher  * Block of information the LLD provides to ULDs attaching to a device.
199f7917c00SJeff Kirsher  */
200f7917c00SJeff Kirsher struct cxgb4_lld_info {
201f7917c00SJeff Kirsher 	struct pci_dev *pdev;                /* associated PCI device */
202f7917c00SJeff Kirsher 	struct l2t_data *l2t;                /* L2 table */
203f7917c00SJeff Kirsher 	struct tid_info *tids;               /* TID table */
204f7917c00SJeff Kirsher 	struct net_device **ports;           /* device ports */
205f7917c00SJeff Kirsher 	const struct cxgb4_virt_res *vr;     /* assorted HW resources */
206f7917c00SJeff Kirsher 	const unsigned short *mtus;          /* MTU table */
207f7917c00SJeff Kirsher 	const unsigned short *rxq_ids;       /* the ULD's Rx queue ids */
208f7917c00SJeff Kirsher 	unsigned short nrxq;                 /* # of Rx queues */
209f7917c00SJeff Kirsher 	unsigned short ntxq;                 /* # of Tx queues */
210f7917c00SJeff Kirsher 	unsigned char nchan:4;               /* # of channels */
211f7917c00SJeff Kirsher 	unsigned char nports:4;              /* # of ports */
212f7917c00SJeff Kirsher 	unsigned char wr_cred;               /* WR 16-byte credits */
213f7917c00SJeff Kirsher 	unsigned char adapter_type;          /* type of adapter */
214f7917c00SJeff Kirsher 	unsigned char fw_api_ver;            /* FW API version */
215f7917c00SJeff Kirsher 	unsigned int fw_vers;                /* FW version */
216f7917c00SJeff Kirsher 	unsigned int iscsi_iolen;            /* iSCSI max I/O length */
217f7917c00SJeff Kirsher 	unsigned short udb_density;          /* # of user DB/page */
218f7917c00SJeff Kirsher 	unsigned short ucq_density;          /* # of user CQs/page */
219f7917c00SJeff Kirsher 	void __iomem *gts_reg;               /* address of GTS register */
220f7917c00SJeff Kirsher 	void __iomem *db_reg;                /* address of kernel doorbell */
221f7917c00SJeff Kirsher };
222f7917c00SJeff Kirsher 
223f7917c00SJeff Kirsher struct cxgb4_uld_info {
224f7917c00SJeff Kirsher 	const char *name;
225f7917c00SJeff Kirsher 	void *(*add)(const struct cxgb4_lld_info *p);
226f7917c00SJeff Kirsher 	int (*rx_handler)(void *handle, const __be64 *rsp,
227f7917c00SJeff Kirsher 			  const struct pkt_gl *gl);
228f7917c00SJeff Kirsher 	int (*state_change)(void *handle, enum cxgb4_state new_state);
229f7917c00SJeff Kirsher };
230f7917c00SJeff Kirsher 
231f7917c00SJeff Kirsher int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p);
232f7917c00SJeff Kirsher int cxgb4_unregister_uld(enum cxgb4_uld type);
233f7917c00SJeff Kirsher int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb);
234*881806bcSVipul Pandya unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo);
235f7917c00SJeff Kirsher unsigned int cxgb4_port_chan(const struct net_device *dev);
236f7917c00SJeff Kirsher unsigned int cxgb4_port_viid(const struct net_device *dev);
237f7917c00SJeff Kirsher unsigned int cxgb4_port_idx(const struct net_device *dev);
238f7917c00SJeff Kirsher unsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu,
239f7917c00SJeff Kirsher 			    unsigned int *idx);
240f7917c00SJeff Kirsher void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4,
241f7917c00SJeff Kirsher 			 struct tp_tcp_stats *v6);
242f7917c00SJeff Kirsher void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask,
243f7917c00SJeff Kirsher 		      const unsigned int *pgsz_order);
244f7917c00SJeff Kirsher struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
245f7917c00SJeff Kirsher 				   unsigned int skb_len, unsigned int pull_len);
246f7917c00SJeff Kirsher #endif  /* !__CXGB4_OFLD_H */
247