xref: /freebsd/sys/dev/cxgb/cxgb_offload.h (revision c5f0f485)
1 
2 /**************************************************************************
3 
4 Copyright (c) 2007-2008, Chelsio Inc.
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10  1. Redistributions of source code must retain the above copyright notice,
11     this list of conditions and the following disclaimer.
12 
13  2. Neither the name of the Chelsio Corporation nor the names of its
14     contributors may be used to endorse or promote products derived from
15     this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 POSSIBILITY OF SUCH DAMAGE.
28 
29 $FreeBSD$
30 
31 ***************************************************************************/
32 
33 #ifndef _CXGB_OFFLOAD_H
34 #define _CXGB_OFFLOAD_H
35 
36 #ifdef CONFIG_DEFINED
37 #include <common/cxgb_version.h>
38 #include <cxgb_config.h>
39 #include <ulp/tom/cxgb_l2t.h>
40 #include <common/cxgb_tcb.h>
41 #include <t3cdev.h>
42 #else
43 #include <dev/cxgb/common/cxgb_version.h>
44 #include <dev/cxgb/cxgb_config.h>
45 #include <dev/cxgb/ulp/tom/cxgb_l2t.h>
46 #include <dev/cxgb/common/cxgb_tcb.h>
47 #include <dev/cxgb/t3cdev.h>
48 #endif
49 
50 MALLOC_DECLARE(M_CXGB);
51 
52 struct adapter;
53 struct cxgb_client;
54 
55 void cxgb_offload_init(void);
56 void cxgb_offload_exit(void);
57 
58 void cxgb_adapter_ofld(struct adapter *adapter);
59 void cxgb_adapter_unofld(struct adapter *adapter);
60 int cxgb_offload_activate(struct adapter *adapter);
61 void cxgb_offload_deactivate(struct adapter *adapter);
62 int cxgb_ofld_recv(struct t3cdev *dev, struct mbuf **m, int n);
63 
64 void cxgb_set_dummy_ops(struct t3cdev *dev);
65 
66 
67 /*
68  * Client registration.  Users of T3 driver must register themselves.
69  * The T3 driver will call the add function of every client for each T3
70  * adapter activated, passing up the t3cdev ptr.  Each client fills out an
71  * array of callback functions to process CPL messages.
72  */
73 
74 void cxgb_register_client(struct cxgb_client *client);
75 void cxgb_unregister_client(struct cxgb_client *client);
76 void cxgb_add_clients(struct t3cdev *tdev);
77 void cxgb_remove_clients(struct t3cdev *tdev);
78 
79 typedef int (*cxgb_cpl_handler_func)(struct t3cdev *dev,
80 				      struct mbuf *m, void *ctx);
81 
82 struct cxgb_client {
83 	char 			*name;
84 	void 			(*add) (struct t3cdev *);
85 	void 			(*remove) (struct t3cdev *);
86 	cxgb_cpl_handler_func 	*handlers;
87 	int			(*redirect)(void *ctx, struct rtentry *old,
88 					    struct rtentry *new,
89 					    struct l2t_entry *l2t);
90 	TAILQ_ENTRY(cxgb_client)         client_entry;
91 };
92 
93 /*
94  * TID allocation services.
95  */
96 int cxgb_alloc_atid(struct t3cdev *dev, struct cxgb_client *client,
97 		     void *ctx);
98 int cxgb_alloc_stid(struct t3cdev *dev, struct cxgb_client *client,
99 		     void *ctx);
100 void *cxgb_free_atid(struct t3cdev *dev, int atid);
101 void cxgb_free_stid(struct t3cdev *dev, int stid);
102 void *cxgb_get_lctx(struct t3cdev *tdev, int stid);
103 void cxgb_insert_tid(struct t3cdev *dev, struct cxgb_client *client,
104 		      void *ctx,
105 	unsigned int tid);
106 void cxgb_queue_tid_release(struct t3cdev *dev, unsigned int tid);
107 void cxgb_remove_tid(struct t3cdev *dev, void *ctx, unsigned int tid);
108 
109 struct toe_tid_entry {
110 	struct cxgb_client 	*client;
111 	void 			*ctx;
112 };
113 
114 /* CPL message priority levels */
115 enum {
116 	CPL_PRIORITY_DATA = 0,     /* data messages */
117 	CPL_PRIORITY_SETUP = 1,	   /* connection setup messages */
118 	CPL_PRIORITY_TEARDOWN = 0, /* connection teardown messages */
119 	CPL_PRIORITY_LISTEN = 1,   /* listen start/stop messages */
120 	CPL_PRIORITY_ACK = 1,      /* RX ACK messages */
121 	CPL_PRIORITY_CONTROL = 1   /* offload control messages */
122 };
123 
124 /* Flags for return value of CPL message handlers */
125 enum {
126 	CPL_RET_BUF_DONE = 1,   // buffer processing done, buffer may be freed
127 	CPL_RET_BAD_MSG = 2,    // bad CPL message (e.g., unknown opcode)
128 	CPL_RET_UNKNOWN_TID = 4	// unexpected unknown TID
129 };
130 
131 typedef int (*cpl_handler_func)(struct t3cdev *dev, struct mbuf *m);
132 
133 /*
134  * Returns a pointer to the first byte of the CPL header in an sk_buff that
135  * contains a CPL message.
136  */
137 static inline void *cplhdr(struct mbuf *m)
138 {
139 	return mtod(m, uint8_t *);
140 }
141 
142 void t3_register_cpl_handler(unsigned int opcode, cpl_handler_func h);
143 
144 union listen_entry {
145 	struct toe_tid_entry toe_tid;
146 	union listen_entry *next;
147 };
148 
149 union active_open_entry {
150 	struct toe_tid_entry toe_tid;
151 	union active_open_entry *next;
152 };
153 
154 /*
155  * Holds the size, base address, free list start, etc of the TID, server TID,
156  * and active-open TID tables for a offload device.
157  * The tables themselves are allocated dynamically.
158  */
159 struct tid_info {
160 	struct toe_tid_entry *tid_tab;
161 	unsigned int ntids;
162 	volatile unsigned int tids_in_use;
163 
164 	union listen_entry *stid_tab;
165 	unsigned int nstids;
166 	unsigned int stid_base;
167 
168 	union active_open_entry *atid_tab;
169 	unsigned int natids;
170 	unsigned int atid_base;
171 
172 	/*
173 	 * The following members are accessed R/W so we put them in their own
174 	 * cache lines.
175 	 *
176 	 * XXX We could combine the atid fields above with the lock here since
177 	 * atids are use once (unlike other tids).  OTOH the above fields are
178 	 * usually in cache due to tid_tab.
179 	 */
180 	struct mtx atid_lock /* ____cacheline_aligned_in_smp */;
181 	union active_open_entry *afree;
182 	unsigned int atids_in_use;
183 
184 	struct mtx stid_lock /*____cacheline_aligned */;
185 	union listen_entry *sfree;
186 	unsigned int stids_in_use;
187 };
188 
189 struct t3c_data {
190 	struct t3cdev *dev;
191 	unsigned int tx_max_chunk;  /* max payload for TX_DATA */
192 	unsigned int max_wrs;       /* max in-flight WRs per connection */
193 	unsigned int nmtus;
194 	const unsigned short *mtus;
195 	struct tid_info tid_maps;
196 
197 	struct toe_tid_entry *tid_release_list;
198 	struct mtx tid_release_lock;
199 	struct task tid_release_task;
200 };
201 
202 /*
203  * t3cdev -> toe_data accessor
204  */
205 #define T3C_DATA(dev) (*(struct t3c_data **)&(dev)->l4opt)
206 
207 /*
208  * Map an ATID or STID to their entries in the corresponding TID tables.
209  */
210 static inline union active_open_entry *atid2entry(const struct tid_info *t,
211                                                   unsigned int atid)
212 {
213         return &t->atid_tab[atid - t->atid_base];
214 }
215 
216 
217 static inline union listen_entry *stid2entry(const struct tid_info *t,
218                                              unsigned int stid)
219 {
220         return &t->stid_tab[stid - t->stid_base];
221 }
222 
223 /*
224  * Find the connection corresponding to a TID.
225  */
226 static inline struct toe_tid_entry *lookup_tid(const struct tid_info *t,
227                                                unsigned int tid)
228 {
229         return tid < t->ntids ? &(t->tid_tab[tid]) : NULL;
230 }
231 
232 /*
233  * Find the connection corresponding to a server TID.
234  */
235 static inline struct toe_tid_entry *lookup_stid(const struct tid_info *t,
236                                                 unsigned int tid)
237 {
238         if (tid < t->stid_base || tid >= t->stid_base + t->nstids)
239                 return NULL;
240         return &(stid2entry(t, tid)->toe_tid);
241 }
242 
243 /*
244  * Find the connection corresponding to an active-open TID.
245  */
246 static inline struct toe_tid_entry *lookup_atid(const struct tid_info *t,
247                                                 unsigned int tid)
248 {
249         if (tid < t->atid_base || tid >= t->atid_base + t->natids)
250                 return NULL;
251         return &(atid2entry(t, tid)->toe_tid);
252 }
253 
254 void *cxgb_alloc_mem(unsigned long size);
255 void cxgb_free_mem(void *addr);
256 void cxgb_neigh_update(struct rtentry *rt, uint8_t *enaddr, struct sockaddr *sa);
257 void cxgb_redirect(struct rtentry *old, struct rtentry *new, struct sockaddr *sa);
258 int process_rx(struct t3cdev *dev, struct mbuf **m, int n);
259 int attach_t3cdev(struct t3cdev *dev);
260 void detach_t3cdev(struct t3cdev *dev);
261 
262 #define CXGB_UNIMPLEMENTED() panic("IMPLEMENT: %s:%s:%d", __FUNCTION__, __FILE__, __LINE__)
263 #endif
264