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