1/************************************************************************** 2 3Copyright (c) 2007, Chelsio Inc. 4All rights reserved. 5 6Redistribution and use in source and binary forms, with or without 7modification, are permitted provided that the following conditions are met: 8 9 1. Redistributions of source code must retain the above copyright notice, 10 this list of conditions and the following disclaimer. 11 12 2. Neither the name of the Chelsio Corporation nor the names of its 13 contributors may be used to endorse or promote products derived from 14 this software without specific prior written permission. 15 16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26POSSIBILITY OF SUCH DAMAGE. 27 28***************************************************************************/ 29 30#include <sys/cdefs.h>
| 1/************************************************************************** 2 3Copyright (c) 2007, Chelsio Inc. 4All rights reserved. 5 6Redistribution and use in source and binary forms, with or without 7modification, are permitted provided that the following conditions are met: 8 9 1. Redistributions of source code must retain the above copyright notice, 10 this list of conditions and the following disclaimer. 11 12 2. Neither the name of the Chelsio Corporation nor the names of its 13 contributors may be used to endorse or promote products derived from 14 this software without specific prior written permission. 15 16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26POSSIBILITY OF SUCH DAMAGE. 27 28***************************************************************************/ 29 30#include <sys/cdefs.h>
|
31__FBSDID("$FreeBSD: head/sys/dev/cxgb/ulp/tom/cxgb_tom.c 174708 2007-12-17 08:17:51Z kmacy $");
| 31__FBSDID("$FreeBSD: head/sys/dev/cxgb/ulp/tom/cxgb_tom.c 176472 2008-02-23 01:06:17Z kmacy $");
|
32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/kernel.h> 36#include <sys/fcntl.h>
| 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/kernel.h> 36#include <sys/fcntl.h>
|
| 37#include <sys/ktr.h>
|
37#include <sys/limits.h> 38#include <sys/lock.h> 39#include <sys/eventhandler.h> 40#include <sys/mbuf.h> 41#include <sys/module.h>
| 38#include <sys/limits.h> 39#include <sys/lock.h> 40#include <sys/eventhandler.h> 41#include <sys/mbuf.h> 42#include <sys/module.h>
|
| 43#include <sys/condvar.h>
|
42#include <sys/mutex.h> 43#include <sys/socket.h> 44#include <sys/sysctl.h> 45#include <sys/syslog.h> 46#include <sys/socketvar.h> 47#include <sys/taskqueue.h> 48 49#include <net/if.h> 50#include <net/route.h> 51 52#include <netinet/in.h> 53#include <netinet/in_pcb.h> 54#include <netinet/in_systm.h> 55#include <netinet/in_var.h> 56 57#include <dev/cxgb/cxgb_osdep.h> 58#include <dev/cxgb/sys/mbufq.h> 59 60#include <netinet/in_pcb.h> 61#include <netinet/tcp.h> 62#include <netinet/tcp_var.h> 63#include <netinet/tcp_offload.h> 64#include <netinet/tcp_fsm.h> 65#include <net/route.h> 66 67#include <dev/cxgb/t3cdev.h> 68#include <dev/cxgb/common/cxgb_firmware_exports.h> 69#include <dev/cxgb/common/cxgb_tcb.h> 70#include <dev/cxgb/cxgb_include.h> 71#include <dev/cxgb/common/cxgb_ctl_defs.h> 72#include <dev/cxgb/common/cxgb_t3_cpl.h> 73#include <dev/cxgb/cxgb_offload.h> 74#include <dev/cxgb/cxgb_l2t.h> 75#include <dev/cxgb/ulp/toecore/cxgb_toedev.h> 76#include <dev/cxgb/ulp/tom/cxgb_tom.h> 77#include <dev/cxgb/ulp/tom/cxgb_defs.h> 78#include <dev/cxgb/ulp/tom/cxgb_t3_ddp.h> 79#include <dev/cxgb/ulp/tom/cxgb_toepcb.h> 80#include <dev/cxgb/ulp/tom/cxgb_tcp.h> 81 82 83static int activated = 1; 84TUNABLE_INT("hw.t3toe.activated", &activated); 85SYSCTL_NODE(_hw, OID_AUTO, t3toe, CTLFLAG_RD, 0, "T3 toe driver parameters"); 86SYSCTL_UINT(_hw_t3toe, OID_AUTO, activated, CTLFLAG_RDTUN, &activated, 0, 87 "enable TOE at init time"); 88 89static TAILQ_HEAD(, tom_data) cxgb_list; 90static struct mtx cxgb_list_lock; 91 92static int t3_toe_attach(struct toedev *dev, const struct offload_id *entry);
| 44#include <sys/mutex.h> 45#include <sys/socket.h> 46#include <sys/sysctl.h> 47#include <sys/syslog.h> 48#include <sys/socketvar.h> 49#include <sys/taskqueue.h> 50 51#include <net/if.h> 52#include <net/route.h> 53 54#include <netinet/in.h> 55#include <netinet/in_pcb.h> 56#include <netinet/in_systm.h> 57#include <netinet/in_var.h> 58 59#include <dev/cxgb/cxgb_osdep.h> 60#include <dev/cxgb/sys/mbufq.h> 61 62#include <netinet/in_pcb.h> 63#include <netinet/tcp.h> 64#include <netinet/tcp_var.h> 65#include <netinet/tcp_offload.h> 66#include <netinet/tcp_fsm.h> 67#include <net/route.h> 68 69#include <dev/cxgb/t3cdev.h> 70#include <dev/cxgb/common/cxgb_firmware_exports.h> 71#include <dev/cxgb/common/cxgb_tcb.h> 72#include <dev/cxgb/cxgb_include.h> 73#include <dev/cxgb/common/cxgb_ctl_defs.h> 74#include <dev/cxgb/common/cxgb_t3_cpl.h> 75#include <dev/cxgb/cxgb_offload.h> 76#include <dev/cxgb/cxgb_l2t.h> 77#include <dev/cxgb/ulp/toecore/cxgb_toedev.h> 78#include <dev/cxgb/ulp/tom/cxgb_tom.h> 79#include <dev/cxgb/ulp/tom/cxgb_defs.h> 80#include <dev/cxgb/ulp/tom/cxgb_t3_ddp.h> 81#include <dev/cxgb/ulp/tom/cxgb_toepcb.h> 82#include <dev/cxgb/ulp/tom/cxgb_tcp.h> 83 84 85static int activated = 1; 86TUNABLE_INT("hw.t3toe.activated", &activated); 87SYSCTL_NODE(_hw, OID_AUTO, t3toe, CTLFLAG_RD, 0, "T3 toe driver parameters"); 88SYSCTL_UINT(_hw_t3toe, OID_AUTO, activated, CTLFLAG_RDTUN, &activated, 0, 89 "enable TOE at init time"); 90 91static TAILQ_HEAD(, tom_data) cxgb_list; 92static struct mtx cxgb_list_lock; 93 94static int t3_toe_attach(struct toedev *dev, const struct offload_id *entry);
|
| 95static void cxgb_register_listeners(void); 96
|
93/* 94 * Handlers for each CPL opcode 95 */
| 97/* 98 * Handlers for each CPL opcode 99 */
|
96static cxgb_cpl_handler_func tom_cpl_handlers[NUM_CPL_CMDS];
| 100static cxgb_cpl_handler_func tom_cpl_handlers[256];
|
97
| 101
|
| 102
|
98static eventhandler_tag listen_tag; 99 100static struct offload_id t3_toe_id_tab[] = { 101 { TOE_ID_CHELSIO_T3, 0 }, 102 { TOE_ID_CHELSIO_T3B, 0 },
| 103static eventhandler_tag listen_tag; 104 105static struct offload_id t3_toe_id_tab[] = { 106 { TOE_ID_CHELSIO_T3, 0 }, 107 { TOE_ID_CHELSIO_T3B, 0 },
|
| 108 { TOE_ID_CHELSIO_T3C, 0 },
|
103 { 0 } 104}; 105 106static struct tom_info t3_tom_info = { 107 .ti_attach = t3_toe_attach, 108 .ti_id_table = t3_toe_id_tab, 109 .ti_name = "Chelsio-T3" 110}; 111 112struct cxgb_client t3c_tom_client = { 113 .name = "tom_cxgb3", 114 .remove = NULL, 115 .handlers = tom_cpl_handlers, 116 .redirect = NULL 117}; 118 119/* 120 * Add an skb to the deferred skb queue for processing from process context. 121 */ 122void 123t3_defer_reply(struct mbuf *m, struct toedev *dev, defer_handler_t handler) 124{ 125 struct tom_data *td = TOM_DATA(dev); 126 127 m_set_handler(m, handler); 128 mtx_lock(&td->deferq.lock); 129 130 mbufq_tail(&td->deferq, m); 131 if (mbufq_len(&td->deferq) == 1) 132 taskqueue_enqueue(td->tq, &td->deferq_task); 133 mtx_lock(&td->deferq.lock); 134} 135 136struct toepcb * 137toepcb_alloc(void) 138{ 139 struct toepcb *toep; 140
| 109 { 0 } 110}; 111 112static struct tom_info t3_tom_info = { 113 .ti_attach = t3_toe_attach, 114 .ti_id_table = t3_toe_id_tab, 115 .ti_name = "Chelsio-T3" 116}; 117 118struct cxgb_client t3c_tom_client = { 119 .name = "tom_cxgb3", 120 .remove = NULL, 121 .handlers = tom_cpl_handlers, 122 .redirect = NULL 123}; 124 125/* 126 * Add an skb to the deferred skb queue for processing from process context. 127 */ 128void 129t3_defer_reply(struct mbuf *m, struct toedev *dev, defer_handler_t handler) 130{ 131 struct tom_data *td = TOM_DATA(dev); 132 133 m_set_handler(m, handler); 134 mtx_lock(&td->deferq.lock); 135 136 mbufq_tail(&td->deferq, m); 137 if (mbufq_len(&td->deferq) == 1) 138 taskqueue_enqueue(td->tq, &td->deferq_task); 139 mtx_lock(&td->deferq.lock); 140} 141 142struct toepcb * 143toepcb_alloc(void) 144{ 145 struct toepcb *toep; 146
|
141 toep = malloc(sizeof(struct toepcb), M_DEVBUF, M_NOWAIT);
| 147 toep = malloc(sizeof(struct toepcb), M_DEVBUF, M_NOWAIT|M_ZERO);
|
142 143 if (toep == NULL) 144 return (NULL); 145 146 toepcb_init(toep); 147 return (toep); 148} 149 150void 151toepcb_init(struct toepcb *toep) 152{
| 148 149 if (toep == NULL) 150 return (NULL); 151 152 toepcb_init(toep); 153 return (toep); 154} 155 156void 157toepcb_init(struct toepcb *toep) 158{
|
153 bzero(toep, sizeof(*toep));
| |
154 toep->tp_refcount = 1;
| 159 toep->tp_refcount = 1;
|
| 160 cv_init(&toep->tp_cv, "toep cv");
|
155} 156 157void 158toepcb_hold(struct toepcb *toep) 159{ 160 atomic_add_acq_int(&toep->tp_refcount, 1); 161} 162 163void 164toepcb_release(struct toepcb *toep) 165{ 166 if (toep->tp_refcount == 1) {
| 161} 162 163void 164toepcb_hold(struct toepcb *toep) 165{ 166 atomic_add_acq_int(&toep->tp_refcount, 1); 167} 168 169void 170toepcb_release(struct toepcb *toep) 171{ 172 if (toep->tp_refcount == 1) {
|
167 printf("doing final toepcb free\n"); 168
| |
169 free(toep, M_DEVBUF); 170 return; 171 }
| 173 free(toep, M_DEVBUF); 174 return; 175 }
|
172
| |
173 atomic_add_acq_int(&toep->tp_refcount, -1); 174} 175 176/* 177 * Add a T3 offload device to the list of devices we are managing. 178 */ 179static void 180t3cdev_add(struct tom_data *t) 181{
| 176 atomic_add_acq_int(&toep->tp_refcount, -1); 177} 178 179/* 180 * Add a T3 offload device to the list of devices we are managing. 181 */ 182static void 183t3cdev_add(struct tom_data *t) 184{
|
182 printf("t3cdev_add\n"); 183
| |
184 mtx_lock(&cxgb_list_lock); 185 TAILQ_INSERT_TAIL(&cxgb_list, t, entry); 186 mtx_unlock(&cxgb_list_lock); 187} 188
| 185 mtx_lock(&cxgb_list_lock); 186 TAILQ_INSERT_TAIL(&cxgb_list, t, entry); 187 mtx_unlock(&cxgb_list_lock); 188} 189
|
| 190static inline int 191cdev2type(struct t3cdev *cdev) 192{ 193 int type = 0; 194 195 switch (cdev->type) { 196 case T3A: 197 type = TOE_ID_CHELSIO_T3; 198 break; 199 case T3B: 200 type = TOE_ID_CHELSIO_T3B; 201 break; 202 case T3C: 203 type = TOE_ID_CHELSIO_T3C; 204 break; 205 } 206 return (type); 207} 208
|
189/* 190 * Allocate a TOM data structure, 191 * initialize its cpl_handlers 192 * and register it as a T3C client 193 */ 194static void 195t3c_tom_add(struct t3cdev *cdev) 196{ 197 int i; 198 unsigned int wr_len; 199 struct tom_data *t; 200 struct toedev *tdev; 201 struct adap_ports *port_info; 202
| 209/* 210 * Allocate a TOM data structure, 211 * initialize its cpl_handlers 212 * and register it as a T3C client 213 */ 214static void 215t3c_tom_add(struct t3cdev *cdev) 216{ 217 int i; 218 unsigned int wr_len; 219 struct tom_data *t; 220 struct toedev *tdev; 221 struct adap_ports *port_info; 222
|
203 printf("%s called\n", __FUNCTION__); 204 205
| |
206 t = malloc(sizeof(*t), M_CXGB, M_NOWAIT|M_ZERO);
| 223 t = malloc(sizeof(*t), M_CXGB, M_NOWAIT|M_ZERO);
|
207
| |
208 if (t == NULL) 209 return; 210 211 if (cdev->ctl(cdev, GET_WR_LEN, &wr_len) < 0) 212 goto out_free_tom; 213 214 port_info = malloc(sizeof(*port_info), M_CXGB, M_NOWAIT|M_ZERO); 215 if (!port_info) 216 goto out_free_tom; 217 218 if (cdev->ctl(cdev, GET_PORTS, port_info) < 0) 219 goto out_free_all; 220 221 t3_init_wr_tab(wr_len); 222 t->cdev = cdev; 223 t->client = &t3c_tom_client; 224 225 /* Register TCP offload device */ 226 tdev = &t->tdev;
| 224 if (t == NULL) 225 return; 226 227 if (cdev->ctl(cdev, GET_WR_LEN, &wr_len) < 0) 228 goto out_free_tom; 229 230 port_info = malloc(sizeof(*port_info), M_CXGB, M_NOWAIT|M_ZERO); 231 if (!port_info) 232 goto out_free_tom; 233 234 if (cdev->ctl(cdev, GET_PORTS, port_info) < 0) 235 goto out_free_all; 236 237 t3_init_wr_tab(wr_len); 238 t->cdev = cdev; 239 t->client = &t3c_tom_client; 240 241 /* Register TCP offload device */ 242 tdev = &t->tdev;
|
227 tdev->tod_ttid = (cdev->type == T3A ? 228 TOE_ID_CHELSIO_T3 : TOE_ID_CHELSIO_T3B);
| 243 tdev->tod_ttid = cdev2type(cdev);
|
229 tdev->tod_lldev = cdev->lldev; 230 231 if (register_toedev(tdev, "toe%d")) { 232 printf("unable to register offload device"); 233 goto out_free_all; 234 } 235 TOM_DATA(tdev) = t; 236
| 244 tdev->tod_lldev = cdev->lldev; 245 246 if (register_toedev(tdev, "toe%d")) { 247 printf("unable to register offload device"); 248 goto out_free_all; 249 } 250 TOM_DATA(tdev) = t; 251
|
237 printf("nports=%d\n", port_info->nports);
| |
238 for (i = 0; i < port_info->nports; i++) { 239 struct ifnet *ifp = port_info->lldevs[i]; 240 TOEDEV(ifp) = tdev; 241
| 252 for (i = 0; i < port_info->nports; i++) { 253 struct ifnet *ifp = port_info->lldevs[i]; 254 TOEDEV(ifp) = tdev; 255
|
242 printf("enabling toe on %p\n", ifp); 243
| 256 CTR1(KTR_TOM, "enabling toe on %p", ifp);
|
244 ifp->if_capabilities |= IFCAP_TOE4; 245 ifp->if_capenable |= IFCAP_TOE4; 246 } 247 t->ports = port_info; 248 249 /* Add device to the list of offload devices */ 250 t3cdev_add(t); 251 252 /* Activate TCP offload device */ 253 activate_offload(tdev);
| 257 ifp->if_capabilities |= IFCAP_TOE4; 258 ifp->if_capenable |= IFCAP_TOE4; 259 } 260 t->ports = port_info; 261 262 /* Add device to the list of offload devices */ 263 t3cdev_add(t); 264 265 /* Activate TCP offload device */ 266 activate_offload(tdev);
|
| 267 cxgb_register_listeners();
|
254 return; 255 256out_free_all: 257 printf("out_free_all fail\n"); 258 free(port_info, M_CXGB); 259out_free_tom: 260 printf("out_free_tom fail\n"); 261 free(t, M_CXGB); 262 return; 263} 264 265/* 266 * Process a received packet with an unknown/unexpected CPL opcode. 267 */ 268static int 269do_bad_cpl(struct t3cdev *cdev, struct mbuf *m, void *ctx) 270{ 271 log(LOG_ERR, "%s: received bad CPL command %u\n", cdev->name,
| 268 return; 269 270out_free_all: 271 printf("out_free_all fail\n"); 272 free(port_info, M_CXGB); 273out_free_tom: 274 printf("out_free_tom fail\n"); 275 free(t, M_CXGB); 276 return; 277} 278 279/* 280 * Process a received packet with an unknown/unexpected CPL opcode. 281 */ 282static int 283do_bad_cpl(struct t3cdev *cdev, struct mbuf *m, void *ctx) 284{ 285 log(LOG_ERR, "%s: received bad CPL command %u\n", cdev->name,
|
272 *mtod(m, unsigned int *)); 273
| 286 0xFF & *mtod(m, unsigned int *)); 287 kdb_backtrace();
|
274 return (CPL_RET_BUF_DONE | CPL_RET_BAD_MSG); 275} 276 277 278/* 279 * Add a new handler to the CPL dispatch table. A NULL handler may be supplied 280 * to unregister an existing handler. 281 */ 282void 283t3tom_register_cpl_handler(unsigned int opcode, cxgb_cpl_handler_func h) 284{
| 288 return (CPL_RET_BUF_DONE | CPL_RET_BAD_MSG); 289} 290 291 292/* 293 * Add a new handler to the CPL dispatch table. A NULL handler may be supplied 294 * to unregister an existing handler. 295 */ 296void 297t3tom_register_cpl_handler(unsigned int opcode, cxgb_cpl_handler_func h) 298{
|
285 if (opcode < NUM_CPL_CMDS)
| 299 if (opcode < 256)
|
286 tom_cpl_handlers[opcode] = h ? h : do_bad_cpl; 287 else 288 log(LOG_ERR, "Chelsio T3 TOM: handler registration for " 289 "opcode %u failed\n", opcode); 290} 291 292/* 293 * Make a preliminary determination if a connection can be offloaded. It's OK 294 * to fail the offload later if we say we can offload here. For now this 295 * always accepts the offload request unless there are IP options. 296 */ 297static int 298can_offload(struct toedev *dev, struct socket *so) 299{ 300 struct tom_data *tomd = TOM_DATA(dev); 301 struct t3cdev *cdev = T3CDEV(dev->tod_lldev); 302 struct tid_info *t = &(T3C_DATA(cdev))->tid_maps; 303 304 return sotoinpcb(so)->inp_depend4.inp4_options == NULL && 305 tomd->conf.activated && 306 (tomd->conf.max_conn < 0 || 307 atomic_load_acq_int(&t->tids_in_use) + t->atids_in_use < tomd->conf.max_conn); 308} 309 310static int 311tom_ctl(struct toedev *dev, unsigned int req, void *data) 312{ 313 struct tom_data *t = TOM_DATA(dev); 314 struct t3cdev *cdev = t->cdev; 315 316 if (cdev->ctl) 317 return cdev->ctl(cdev, req, data); 318 319 return (EOPNOTSUPP); 320} 321 322/* 323 * Initialize the CPL dispatch table. 324 */ 325static void 326init_cpl_handlers(void) 327{ 328 int i; 329
| 300 tom_cpl_handlers[opcode] = h ? h : do_bad_cpl; 301 else 302 log(LOG_ERR, "Chelsio T3 TOM: handler registration for " 303 "opcode %u failed\n", opcode); 304} 305 306/* 307 * Make a preliminary determination if a connection can be offloaded. It's OK 308 * to fail the offload later if we say we can offload here. For now this 309 * always accepts the offload request unless there are IP options. 310 */ 311static int 312can_offload(struct toedev *dev, struct socket *so) 313{ 314 struct tom_data *tomd = TOM_DATA(dev); 315 struct t3cdev *cdev = T3CDEV(dev->tod_lldev); 316 struct tid_info *t = &(T3C_DATA(cdev))->tid_maps; 317 318 return sotoinpcb(so)->inp_depend4.inp4_options == NULL && 319 tomd->conf.activated && 320 (tomd->conf.max_conn < 0 || 321 atomic_load_acq_int(&t->tids_in_use) + t->atids_in_use < tomd->conf.max_conn); 322} 323 324static int 325tom_ctl(struct toedev *dev, unsigned int req, void *data) 326{ 327 struct tom_data *t = TOM_DATA(dev); 328 struct t3cdev *cdev = t->cdev; 329 330 if (cdev->ctl) 331 return cdev->ctl(cdev, req, data); 332 333 return (EOPNOTSUPP); 334} 335 336/* 337 * Initialize the CPL dispatch table. 338 */ 339static void 340init_cpl_handlers(void) 341{ 342 int i; 343
|
330 for (i = 0; i < NUM_CPL_CMDS; ++i)
| 344 for (i = 0; i < 256; ++i)
|
331 tom_cpl_handlers[i] = do_bad_cpl; 332 333 t3_init_listen_cpl_handlers(); 334} 335 336static int 337t3_toe_attach(struct toedev *dev, const struct offload_id *entry) 338{ 339 struct tom_data *t = TOM_DATA(dev); 340 struct t3cdev *cdev = t->cdev; 341 struct ddp_params ddp; 342 struct ofld_page_info rx_page_info; 343 int err; 344 345#if 0 346 skb_queue_head_init(&t->deferq); 347 T3_INIT_WORK(&t->deferq_task, process_deferq, t); 348 spin_lock_init(&t->listen_lock); 349#endif 350 t3_init_tunables(t); 351 mtx_init(&t->listen_lock, "tom data listeners", NULL, MTX_DEF);
| 345 tom_cpl_handlers[i] = do_bad_cpl; 346 347 t3_init_listen_cpl_handlers(); 348} 349 350static int 351t3_toe_attach(struct toedev *dev, const struct offload_id *entry) 352{ 353 struct tom_data *t = TOM_DATA(dev); 354 struct t3cdev *cdev = t->cdev; 355 struct ddp_params ddp; 356 struct ofld_page_info rx_page_info; 357 int err; 358 359#if 0 360 skb_queue_head_init(&t->deferq); 361 T3_INIT_WORK(&t->deferq_task, process_deferq, t); 362 spin_lock_init(&t->listen_lock); 363#endif 364 t3_init_tunables(t); 365 mtx_init(&t->listen_lock, "tom data listeners", NULL, MTX_DEF);
|
352
| 366 CTR2(KTR_TOM, "t3_toe_attach dev=%p entry=%p", dev, entry);
|
353 /* Adjust TOE activation for this module */ 354 t->conf.activated = activated; 355 356 dev->tod_can_offload = can_offload; 357 dev->tod_connect = t3_connect; 358 dev->tod_ctl = tom_ctl; 359#if 0 360#ifndef NETEVENT 361 dev->tod_neigh_update = tom_neigh_update; 362#endif 363 dev->tod_failover = t3_failover; 364#endif 365 err = cdev->ctl(cdev, GET_DDP_PARAMS, &ddp); 366 if (err) 367 return err; 368 369 err = cdev->ctl(cdev, GET_RX_PAGE_INFO, &rx_page_info); 370 if (err) 371 return err; 372 373 t->ddp_llimit = ddp.llimit; 374 t->ddp_ulimit = ddp.ulimit; 375 t->pdev = ddp.pdev; 376 t->rx_page_size = rx_page_info.page_size;
| 367 /* Adjust TOE activation for this module */ 368 t->conf.activated = activated; 369 370 dev->tod_can_offload = can_offload; 371 dev->tod_connect = t3_connect; 372 dev->tod_ctl = tom_ctl; 373#if 0 374#ifndef NETEVENT 375 dev->tod_neigh_update = tom_neigh_update; 376#endif 377 dev->tod_failover = t3_failover; 378#endif 379 err = cdev->ctl(cdev, GET_DDP_PARAMS, &ddp); 380 if (err) 381 return err; 382 383 err = cdev->ctl(cdev, GET_RX_PAGE_INFO, &rx_page_info); 384 if (err) 385 return err; 386 387 t->ddp_llimit = ddp.llimit; 388 t->ddp_ulimit = ddp.ulimit; 389 t->pdev = ddp.pdev; 390 t->rx_page_size = rx_page_info.page_size;
|
377#ifdef notyet
| |
378 /* OK if this fails, we just can't do DDP */ 379 t->nppods = (ddp.ulimit + 1 - ddp.llimit) / PPOD_SIZE;
| 391 /* OK if this fails, we just can't do DDP */ 392 t->nppods = (ddp.ulimit + 1 - ddp.llimit) / PPOD_SIZE;
|
380 t->ppod_map = t3_alloc_mem(t->nppods); 381#endif
| 393 t->ppod_map = malloc(t->nppods, M_DEVBUF, M_WAITOK|M_ZERO);
|
382
| 394
|
383#if 0 384 spin_lock_init(&t->ppod_map_lock); 385 tom_proc_init(dev); 386#ifdef CONFIG_SYSCTL 387 t->sysctl = t3_sysctl_register(dev, &t->conf); 388#endif 389#endif
| 395 mtx_init(&t->ppod_map_lock, "ppod map", NULL, MTX_DEF); 396 397 398 t3_sysctl_register(cdev->adapter, &t->conf);
|
390 return (0); 391} 392 393static void 394cxgb_toe_listen_start(void *unused, struct tcpcb *tp) 395{ 396 struct socket *so = tp->t_inpcb->inp_socket; 397 struct tom_data *p; 398 399 mtx_lock(&cxgb_list_lock); 400 TAILQ_FOREACH(p, &cxgb_list, entry) { 401 t3_listen_start(&p->tdev, so, p->cdev); 402 } 403 mtx_unlock(&cxgb_list_lock); 404} 405 406static void 407cxgb_toe_listen_stop(void *unused, struct tcpcb *tp) 408{ 409 struct socket *so = tp->t_inpcb->inp_socket; 410 struct tom_data *p; 411 412 mtx_lock(&cxgb_list_lock); 413 TAILQ_FOREACH(p, &cxgb_list, entry) {
| 399 return (0); 400} 401 402static void 403cxgb_toe_listen_start(void *unused, struct tcpcb *tp) 404{ 405 struct socket *so = tp->t_inpcb->inp_socket; 406 struct tom_data *p; 407 408 mtx_lock(&cxgb_list_lock); 409 TAILQ_FOREACH(p, &cxgb_list, entry) { 410 t3_listen_start(&p->tdev, so, p->cdev); 411 } 412 mtx_unlock(&cxgb_list_lock); 413} 414 415static void 416cxgb_toe_listen_stop(void *unused, struct tcpcb *tp) 417{ 418 struct socket *so = tp->t_inpcb->inp_socket; 419 struct tom_data *p; 420 421 mtx_lock(&cxgb_list_lock); 422 TAILQ_FOREACH(p, &cxgb_list, entry) {
|
414 if (tp->t_state == TCPS_LISTEN) { 415 printf("stopping listen on port=%d\n", 416 ntohs(tp->t_inpcb->inp_lport));
| 423 if (tp->t_state == TCPS_LISTEN)
|
417 t3_listen_stop(&p->tdev, so, p->cdev);
| 424 t3_listen_stop(&p->tdev, so, p->cdev);
|
418 }
| |
419 } 420 mtx_unlock(&cxgb_list_lock); 421} 422 423static void 424cxgb_register_listeners(void) 425{ 426 struct inpcb *inp; 427 struct tcpcb *tp; 428 429 INP_INFO_RLOCK(&tcbinfo); 430 LIST_FOREACH(inp, tcbinfo.ipi_listhead, inp_list) { 431 tp = intotcpcb(inp); 432 433 if (tp->t_state == TCPS_LISTEN) 434 cxgb_toe_listen_start(NULL, tp); 435 } 436 INP_INFO_RUNLOCK(&tcbinfo); 437} 438 439static int 440t3_tom_init(void) 441{
| 425 } 426 mtx_unlock(&cxgb_list_lock); 427} 428 429static void 430cxgb_register_listeners(void) 431{ 432 struct inpcb *inp; 433 struct tcpcb *tp; 434 435 INP_INFO_RLOCK(&tcbinfo); 436 LIST_FOREACH(inp, tcbinfo.ipi_listhead, inp_list) { 437 tp = intotcpcb(inp); 438 439 if (tp->t_state == TCPS_LISTEN) 440 cxgb_toe_listen_start(NULL, tp); 441 } 442 INP_INFO_RUNLOCK(&tcbinfo); 443} 444 445static int 446t3_tom_init(void) 447{
|
442 443#if 0 444 struct socket *sock; 445 err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); 446 if (err < 0) { 447 printk(KERN_ERR "Could not create TCP socket, error %d\n", err); 448 return err; 449 } 450 451 t3_def_state_change = sock->sk->sk_state_change; 452 t3_def_data_ready = sock->sk->sk_data_ready; 453 t3_def_error_report = sock->sk->sk_error_report; 454 sock_release(sock); 455#endif
| |
456 init_cpl_handlers();
| 448 init_cpl_handlers();
|
457 if (t3_init_cpl_io() < 0)
| 449 if (t3_init_cpl_io() < 0) { 450 log(LOG_ERR, 451 "Unable to initialize cpl io ops\n");
|
458 return -1;
| 452 return -1;
|
| 453 }
|
459 t3_init_socket_ops(); 460 461 /* Register with the TOE device layer. */ 462 463 if (register_tom(&t3_tom_info) != 0) { 464 log(LOG_ERR, 465 "Unable to register Chelsio T3 TCP offload module.\n"); 466 return -1; 467 } 468 INP_INFO_WLOCK(&tcbinfo);
| 454 t3_init_socket_ops(); 455 456 /* Register with the TOE device layer. */ 457 458 if (register_tom(&t3_tom_info) != 0) { 459 log(LOG_ERR, 460 "Unable to register Chelsio T3 TCP offload module.\n"); 461 return -1; 462 } 463 INP_INFO_WLOCK(&tcbinfo);
|
469
| |
470 INP_INFO_WUNLOCK(&tcbinfo); 471 472 mtx_init(&cxgb_list_lock, "cxgb tom list", NULL, MTX_DEF); 473 listen_tag = EVENTHANDLER_REGISTER(tcp_offload_listen_start, 474 cxgb_toe_listen_start, NULL, EVENTHANDLER_PRI_ANY); 475 listen_tag = EVENTHANDLER_REGISTER(tcp_offload_listen_stop, 476 cxgb_toe_listen_stop, NULL, EVENTHANDLER_PRI_ANY); 477 TAILQ_INIT(&cxgb_list); 478 479 /* Register to offloading devices */
| 464 INP_INFO_WUNLOCK(&tcbinfo); 465 466 mtx_init(&cxgb_list_lock, "cxgb tom list", NULL, MTX_DEF); 467 listen_tag = EVENTHANDLER_REGISTER(tcp_offload_listen_start, 468 cxgb_toe_listen_start, NULL, EVENTHANDLER_PRI_ANY); 469 listen_tag = EVENTHANDLER_REGISTER(tcp_offload_listen_stop, 470 cxgb_toe_listen_stop, NULL, EVENTHANDLER_PRI_ANY); 471 TAILQ_INIT(&cxgb_list); 472 473 /* Register to offloading devices */
|
480 printf("setting add to %p\n", t3c_tom_add);
| |
481 t3c_tom_client.add = t3c_tom_add; 482 cxgb_register_client(&t3c_tom_client);
| 474 t3c_tom_client.add = t3c_tom_add; 475 cxgb_register_client(&t3c_tom_client);
|
483 cxgb_register_listeners();
| |
484 return (0); 485} 486 487static int 488t3_tom_load(module_t mod, int cmd, void *arg) 489{ 490 int err = 0; 491 492 switch (cmd) { 493 case MOD_LOAD:
| 476 return (0); 477} 478 479static int 480t3_tom_load(module_t mod, int cmd, void *arg) 481{ 482 int err = 0; 483 484 switch (cmd) { 485 case MOD_LOAD:
|
494 printf("wheeeeee ...\n"); 495
| |
496 t3_tom_init(); 497 break; 498 case MOD_QUIESCE: 499 break; 500 case MOD_UNLOAD: 501 printf("uhm, ... unloading isn't really supported for toe\n"); 502 break; 503 case MOD_SHUTDOWN: 504 break; 505 default: 506 err = EOPNOTSUPP; 507 break; 508 } 509 510 return (err); 511} 512 513static moduledata_t mod_data= { 514 "t3_tom", 515 t3_tom_load, 516 0 517}; 518MODULE_VERSION(t3_tom, 1); 519MODULE_DEPEND(t3_tom, toecore, 1, 1, 1); 520MODULE_DEPEND(t3_tom, if_cxgb, 1, 1, 1); 521DECLARE_MODULE(t3_tom, mod_data, SI_SUB_EXEC, SI_ORDER_ANY); 522
| 486 t3_tom_init(); 487 break; 488 case MOD_QUIESCE: 489 break; 490 case MOD_UNLOAD: 491 printf("uhm, ... unloading isn't really supported for toe\n"); 492 break; 493 case MOD_SHUTDOWN: 494 break; 495 default: 496 err = EOPNOTSUPP; 497 break; 498 } 499 500 return (err); 501} 502 503static moduledata_t mod_data= { 504 "t3_tom", 505 t3_tom_load, 506 0 507}; 508MODULE_VERSION(t3_tom, 1); 509MODULE_DEPEND(t3_tom, toecore, 1, 1, 1); 510MODULE_DEPEND(t3_tom, if_cxgb, 1, 1, 1); 511DECLARE_MODULE(t3_tom, mod_data, SI_SUB_EXEC, SI_ORDER_ANY); 512
|