1
2 /**************************************************************************
3
4 Copyright (c) 2007, 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
30 ***************************************************************************/
31
32
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: cxgb_offload.c,v 1.7 2021/08/08 20:57:09 andvar Exp $");
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/kernel.h>
39 #include <sys/conf.h>
40 #include <sys/bus.h>
41 #include <sys/ioccom.h>
42 #include <sys/mbuf.h>
43 #include <sys/socket.h>
44 #include <sys/sockio.h>
45 #include <sys/sysctl.h>
46 #include <sys/queue.h>
47
48 #ifdef CONFIG_DEFINED
49 #include <cxgb_include.h>
50 #else
51 #include "cxgb_include.h"
52 #endif
53
54 #include <net/route.h>
55
56 /*
57 * XXX
58 */
59 #define LOG_NOTICE 2
60 #define BUG_ON(...)
61 #define VALIDATE_TID 0
62
63
64 TAILQ_HEAD(, cxgb_client) client_list;
65 TAILQ_HEAD(, toedev) ofld_dev_list;
66 TAILQ_HEAD(, adapter) adapter_list;
67
68 static struct mtx cxgb_db_lock;
69 static struct rwlock adapter_list_lock;
70
71
72 static const unsigned int MAX_ATIDS = 64 * 1024;
73 static const unsigned int ATID_BASE = 0x100000;
74 static int inited = 0;
75
76 static inline int
offload_activated(struct toedev * tdev)77 offload_activated(struct toedev *tdev)
78 {
79 struct adapter *adapter = tdev2adap(tdev);
80
81 return (isset(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT));
82 }
83
84 /**
85 * cxgb_register_client - register an offload client
86 * @client: the client
87 *
88 * Add the client to the client list,
89 * and call backs the client for each activated offload device
90 */
91 void
cxgb_register_client(struct cxgb_client * client)92 cxgb_register_client(struct cxgb_client *client)
93 {
94 struct toedev *tdev;
95
96 mtx_lock(&cxgb_db_lock);
97 TAILQ_INSERT_TAIL(&client_list, client, client_entry);
98
99 if (client->add) {
100 TAILQ_FOREACH(tdev, &ofld_dev_list, ofld_entry) {
101 if (offload_activated(tdev))
102 client->add(tdev);
103 }
104 }
105 mtx_unlock(&cxgb_db_lock);
106 }
107
108 /**
109 * cxgb_unregister_client - unregister an offload client
110 * @client: the client
111 *
112 * Remove the client to the client list,
113 * and call backs the client for each activated offload device.
114 */
115 void
cxgb_unregister_client(struct cxgb_client * client)116 cxgb_unregister_client(struct cxgb_client *client)
117 {
118 struct toedev *tdev;
119
120 mtx_lock(&cxgb_db_lock);
121 TAILQ_REMOVE(&client_list, client, client_entry);
122
123 if (client->remove) {
124 TAILQ_FOREACH(tdev, &ofld_dev_list, ofld_entry) {
125 if (offload_activated(tdev))
126 client->remove(tdev);
127 }
128 }
129 mtx_unlock(&cxgb_db_lock);
130 }
131
132 /**
133 * cxgb_add_clients - activate register clients for an offload device
134 * @tdev: the offload device
135 *
136 * Call backs all registered clients once a offload device is activated
137 */
138 void
cxgb_add_clients(struct toedev * tdev)139 cxgb_add_clients(struct toedev *tdev)
140 {
141 struct cxgb_client *client;
142
143 mtx_lock(&cxgb_db_lock);
144 TAILQ_FOREACH(client, &client_list, client_entry) {
145 if (client->add)
146 client->add(tdev);
147 }
148 mtx_unlock(&cxgb_db_lock);
149 }
150
151 /**
152 * cxgb_remove_clients - activate register clients for an offload device
153 * @tdev: the offload device
154 *
155 * Call backs all registered clients once a offload device is deactivated
156 */
157 void
cxgb_remove_clients(struct toedev * tdev)158 cxgb_remove_clients(struct toedev *tdev)
159 {
160 struct cxgb_client *client;
161
162 mtx_lock(&cxgb_db_lock);
163 TAILQ_FOREACH(client, &client_list, client_entry) {
164 if (client->remove)
165 client->remove(tdev);
166 }
167 mtx_unlock(&cxgb_db_lock);
168 }
169
170 static int
is_offloading(struct ifnet * ifp)171 is_offloading(struct ifnet *ifp)
172 {
173 struct adapter *adapter;
174 int port;
175
176 rw_rlock(&adapter_list_lock);
177 TAILQ_FOREACH(adapter, &adapter_list, adapter_entry) {
178 for_each_port(adapter, port) {
179 if (ifp == adapter->port[port].ifp) {
180 rw_runlock(&adapter_list_lock);
181 return 1;
182 }
183 }
184 }
185 rw_runlock(&adapter_list_lock);
186 return 0;
187 }
188
189 static struct ifnet *
get_iff_from_mac(adapter_t * adapter,const uint8_t * mac,unsigned int vlan)190 get_iff_from_mac(adapter_t *adapter, const uint8_t *mac, unsigned int vlan)
191 {
192 #ifdef notyet
193 int i;
194
195 for_each_port(adapter, i) {
196 const struct vlan_group *grp;
197 const struct port_info *p = &adapter->port[i];
198 struct ifnet *ifnet = p->ifp;
199
200 if (!memcmp(p->hw_addr, mac, ETHER_ADDR_LEN)) {
201 if (vlan && vlan != EVL_VLID_MASK) {
202 grp = p->vlan_grp;
203 dev = grp ? grp->vlan_devices[vlan] : NULL;
204 } else
205 while (dev->master)
206 dev = dev->master;
207 return dev;
208 }
209 }
210 #endif
211 return NULL;
212 }
213
214 static inline void
failover_fixup(adapter_t * adapter,int port)215 failover_fixup(adapter_t *adapter, int port)
216 {
217 if (adapter->params.rev == 0) {
218 struct ifnet *ifp = adapter->port[port].ifp;
219 struct cmac *mac = &adapter->port[port].mac;
220 if (!(ifp->if_flags & IFF_UP)) {
221 /* Failover triggered by the interface ifdown */
222 t3_write_reg(adapter, A_XGM_TX_CTRL + mac->offset,
223 F_TXEN);
224 t3_read_reg(adapter, A_XGM_TX_CTRL + mac->offset);
225 } else {
226 /* Failover triggered by the interface link down */
227 t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0);
228 t3_read_reg(adapter, A_XGM_RX_CTRL + mac->offset);
229 t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset,
230 F_RXEN);
231 }
232 }
233 }
234
235 static int
cxgb_ulp_iscsi_ctl(adapter_t * adapter,unsigned int req,void * data)236 cxgb_ulp_iscsi_ctl(adapter_t *adapter, unsigned int req, void *data)
237 {
238 int ret = 0;
239 struct ulp_iscsi_info *uiip = data;
240
241 switch (req) {
242 case ULP_ISCSI_GET_PARAMS:
243 uiip->llimit = t3_read_reg(adapter, A_ULPRX_ISCSI_LLIMIT);
244 uiip->ulimit = t3_read_reg(adapter, A_ULPRX_ISCSI_ULIMIT);
245 uiip->tagmask = t3_read_reg(adapter, A_ULPRX_ISCSI_TAGMASK);
246 /*
247 * On tx, the iscsi pdu has to be <= tx page size and has to
248 * fit into the Tx PM FIFO.
249 */
250 uiip->max_txsz = uimin(adapter->params.tp.tx_pg_size,
251 t3_read_reg(adapter, A_PM1_TX_CFG) >> 17);
252 /* on rx, the iscsi pdu has to be < rx page size and the
253 whole pdu + cpl headers has to fit into one sge buffer */
254 uiip->max_rxsz =
255 (unsigned int)uimin(adapter->params.tp.rx_pg_size,
256 (adapter->sge.qs[0].fl[1].buf_size -
257 sizeof(struct cpl_rx_data) * 2 -
258 sizeof(struct cpl_rx_data_ddp)) );
259 break;
260 case ULP_ISCSI_SET_PARAMS:
261 t3_write_reg(adapter, A_ULPRX_ISCSI_TAGMASK, uiip->tagmask);
262 break;
263 default:
264 ret = (EOPNOTSUPP);
265 }
266 return ret;
267 }
268
269 /* Response queue used for RDMA events. */
270 #define ASYNC_NOTIF_RSPQ 0
271
272 static int
cxgb_rdma_ctl(adapter_t * adapter,unsigned int req,void * data)273 cxgb_rdma_ctl(adapter_t *adapter, unsigned int req, void *data)
274 {
275 int ret = 0;
276
277 switch (req) {
278 case RDMA_GET_PARAMS: {
279 struct rdma_info *req2 = data;
280
281 req2->tpt_base = t3_read_reg(adapter, A_ULPTX_TPT_LLIMIT);
282 req2->tpt_top = t3_read_reg(adapter, A_ULPTX_TPT_ULIMIT);
283 req2->pbl_base = t3_read_reg(adapter, A_ULPTX_PBL_LLIMIT);
284 req2->pbl_top = t3_read_reg(adapter, A_ULPTX_PBL_ULIMIT);
285 req2->rqt_base = t3_read_reg(adapter, A_ULPRX_RQ_LLIMIT);
286 req2->rqt_top = t3_read_reg(adapter, A_ULPRX_RQ_ULIMIT);
287 break;
288 }
289 case RDMA_CQ_OP: {
290 struct rdma_cq_op *req2 = data;
291
292 /* may be called in any context */
293 mtx_lock(&adapter->sge.reg_lock);
294 ret = t3_sge_cqcntxt_op(adapter, req2->id, req2->op,
295 req2->credits);
296 mtx_unlock(&adapter->sge.reg_lock);
297 break;
298 }
299 case RDMA_GET_MEM: {
300 struct ch_mem_range *t = data;
301 struct mc7 *mem;
302
303 if ((t->addr & 7) || (t->len & 7))
304 return (EINVAL);
305 if (t->mem_id == MEM_CM)
306 mem = &adapter->cm;
307 else if (t->mem_id == MEM_PMRX)
308 mem = &adapter->pmrx;
309 else if (t->mem_id == MEM_PMTX)
310 mem = &adapter->pmtx;
311 else
312 return (EINVAL);
313
314 ret = t3_mc7_bd_read(mem, t->addr/8, t->len/8, (u64 *)t->buf);
315 if (ret)
316 return (ret);
317 break;
318 }
319 case RDMA_CQ_SETUP: {
320 struct rdma_cq_setup *req2 = data;
321
322 mtx_lock(&adapter->sge.reg_lock);
323 ret = t3_sge_init_cqcntxt(adapter, req2->id, req2->base_addr,
324 req2->size, ASYNC_NOTIF_RSPQ,
325 req2->ovfl_mode, req2->credits,
326 req2->credit_thres);
327 mtx_unlock(&adapter->sge.reg_lock);
328 break;
329 }
330 case RDMA_CQ_DISABLE:
331 mtx_lock(&adapter->sge.reg_lock);
332 ret = t3_sge_disable_cqcntxt(adapter, *(unsigned int *)data);
333 mtx_unlock(&adapter->sge.reg_lock);
334 break;
335 case RDMA_CTRL_QP_SETUP: {
336 struct rdma_ctrlqp_setup *req2 = data;
337
338 mtx_lock(&adapter->sge.reg_lock);
339 ret = t3_sge_init_ecntxt(adapter, FW_RI_SGEEC_START, 0,
340 SGE_CNTXT_RDMA, ASYNC_NOTIF_RSPQ,
341 req2->base_addr, req2->size,
342 FW_RI_TID_START, 1, 0);
343 mtx_unlock(&adapter->sge.reg_lock);
344 break;
345 }
346 default:
347 ret = EOPNOTSUPP;
348 }
349 return (ret);
350 }
351
352 static int
cxgb_offload_ctl(struct toedev * tdev,unsigned int req,void * data)353 cxgb_offload_ctl(struct toedev *tdev, unsigned int req, void *data)
354 {
355 struct adapter *adapter = tdev2adap(tdev);
356 struct tid_range *tid;
357 struct mtutab *mtup;
358 struct iff_mac *iffmacp;
359 struct ddp_params *ddpp;
360 struct adap_ports *ports;
361 int port;
362
363 switch (req) {
364 case GET_MAX_OUTSTANDING_WR:
365 *(unsigned int *)data = FW_WR_NUM;
366 break;
367 case GET_WR_LEN:
368 *(unsigned int *)data = WR_FLITS;
369 break;
370 case GET_TX_MAX_CHUNK:
371 *(unsigned int *)data = 1 << 20; /* 1MB */
372 break;
373 case GET_TID_RANGE:
374 tid = data;
375 tid->num = t3_mc5_size(&adapter->mc5) -
376 adapter->params.mc5.nroutes -
377 adapter->params.mc5.nfilters -
378 adapter->params.mc5.nservers;
379 tid->base = 0;
380 break;
381 case GET_STID_RANGE:
382 tid = data;
383 tid->num = adapter->params.mc5.nservers;
384 tid->base = t3_mc5_size(&adapter->mc5) - tid->num -
385 adapter->params.mc5.nfilters -
386 adapter->params.mc5.nroutes;
387 break;
388 case GET_L2T_CAPACITY:
389 *(unsigned int *)data = 2048;
390 break;
391 case GET_MTUS:
392 mtup = data;
393 mtup->size = NMTUS;
394 mtup->mtus = adapter->params.mtus;
395 break;
396 case GET_IFF_FROM_MAC:
397 iffmacp = data;
398 iffmacp->dev = get_iff_from_mac(adapter, iffmacp->mac_addr,
399 iffmacp->vlan_tag & EVL_VLID_MASK);
400 break;
401 case GET_DDP_PARAMS:
402 ddpp = data;
403 ddpp->llimit = t3_read_reg(adapter, A_ULPRX_TDDP_LLIMIT);
404 ddpp->ulimit = t3_read_reg(adapter, A_ULPRX_TDDP_ULIMIT);
405 ddpp->tag_mask = t3_read_reg(adapter, A_ULPRX_TDDP_TAGMASK);
406 break;
407 case GET_PORTS:
408 ports = data;
409 ports->nports = adapter->params.nports;
410 for_each_port(adapter, port)
411 ports->lldevs[port] = adapter->port[port].ifp;
412 break;
413 case FAILOVER:
414 port = *(int *)data;
415 t3_port_failover(adapter, port);
416 failover_fixup(adapter, port);
417 break;
418 case FAILOVER_DONE:
419 port = *(int *)data;
420 t3_failover_done(adapter, port);
421 break;
422 case FAILOVER_CLEAR:
423 t3_failover_clear(adapter);
424 break;
425 case ULP_ISCSI_GET_PARAMS:
426 case ULP_ISCSI_SET_PARAMS:
427 if (!offload_running(adapter))
428 return (EAGAIN);
429 return cxgb_ulp_iscsi_ctl(adapter, req, data);
430 case RDMA_GET_PARAMS:
431 case RDMA_CQ_OP:
432 case RDMA_CQ_SETUP:
433 case RDMA_CQ_DISABLE:
434 case RDMA_CTRL_QP_SETUP:
435 case RDMA_GET_MEM:
436 if (!offload_running(adapter))
437 return (EAGAIN);
438 return cxgb_rdma_ctl(adapter, req, data);
439 default:
440 return (EOPNOTSUPP);
441 }
442 return 0;
443 }
444
445 /*
446 * Dummy handler for Rx offload packets in case we get an offload packet before
447 * proper processing is setup. This complains and drops the packet as it isn't
448 * normal to get offload packets at this stage.
449 */
450 static int
rx_offload_blackhole(struct toedev * dev,struct mbuf ** m,int n)451 rx_offload_blackhole(struct toedev *dev, struct mbuf **m, int n)
452 {
453 CH_ERR(tdev2adap(dev), "%d unexpected offload packets, first data 0x%x\n",
454 n, *mtod(m[0], uint32_t *));
455 while (n--)
456 m_freem(m[n]);
457 return 0;
458 }
459
460 static void
dummy_neigh_update(struct toedev * dev,struct rtentry * neigh)461 dummy_neigh_update(struct toedev *dev, struct rtentry *neigh)
462 {
463 }
464
465 void
cxgb_set_dummy_ops(struct toedev * dev)466 cxgb_set_dummy_ops(struct toedev *dev)
467 {
468 dev->recv = rx_offload_blackhole;
469 dev->neigh_update = dummy_neigh_update;
470 }
471
472 /*
473 * Free an active-open TID.
474 */
475 void *
cxgb_free_atid(struct toedev * tdev,int atid)476 cxgb_free_atid(struct toedev *tdev, int atid)
477 {
478 struct tid_info *t = &(TOE_DATA(tdev))->tid_maps;
479 union active_open_entry *p = atid2entry(t, atid);
480 void *ctx = p->toe_tid.ctx;
481
482 mtx_lock(&t->atid_lock);
483 p->next = t->afree;
484 t->afree = p;
485 t->atids_in_use--;
486 mtx_lock(&t->atid_lock);
487
488 return ctx;
489 }
490
491 /*
492 * Free a server TID and return it to the free pool.
493 */
494 void
cxgb_free_stid(struct toedev * tdev,int stid)495 cxgb_free_stid(struct toedev *tdev, int stid)
496 {
497 struct tid_info *t = &(TOE_DATA(tdev))->tid_maps;
498 union listen_entry *p = stid2entry(t, stid);
499
500 mtx_lock(&t->stid_lock);
501 p->next = t->sfree;
502 t->sfree = p;
503 t->stids_in_use--;
504 mtx_unlock(&t->stid_lock);
505 }
506
507 void
cxgb_insert_tid(struct toedev * tdev,struct cxgb_client * client,void * ctx,unsigned int tid)508 cxgb_insert_tid(struct toedev *tdev, struct cxgb_client *client,
509 void *ctx, unsigned int tid)
510 {
511 struct tid_info *t = &(TOE_DATA(tdev))->tid_maps;
512
513 t->tid_tab[tid].client = client;
514 t->tid_tab[tid].ctx = ctx;
515 atomic_add_int(&t->tids_in_use, 1);
516 }
517
518 /*
519 * Populate a TID_RELEASE WR. The mbuf must be already properly sized.
520 */
521 static inline void
mk_tid_release(struct mbuf * m,unsigned int tid)522 mk_tid_release(struct mbuf *m, unsigned int tid)
523 {
524 struct cpl_tid_release *req;
525
526 m_set_priority(m, CPL_PRIORITY_SETUP);
527 req = mtod(m, struct cpl_tid_release *);
528 req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
529 OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, tid));
530 }
531
532 static void
t3_process_tid_release_list(struct work * wk,void * data)533 t3_process_tid_release_list(struct work *wk, void *data)
534 {
535 struct mbuf *m;
536 struct toedev *tdev = data;
537 struct toe_data *td = TOE_DATA(tdev);
538
539 mtx_lock(&td->tid_release_lock);
540 while (td->tid_release_list) {
541 struct toe_tid_entry *p = td->tid_release_list;
542
543 td->tid_release_list = (struct toe_tid_entry *)p->ctx;
544 mtx_unlock(&td->tid_release_lock);
545 m = m_get(M_WAIT, MT_DATA);
546 mk_tid_release(m, p - td->tid_maps.tid_tab);
547 cxgb_ofld_send(tdev, m);
548 p->ctx = NULL;
549 mtx_lock(&td->tid_release_lock);
550 }
551 mtx_unlock(&td->tid_release_lock);
552 }
553
554 /* use ctx as a next pointer in the tid release list */
555 void
cxgb_queue_tid_release(struct toedev * tdev,unsigned int tid)556 cxgb_queue_tid_release(struct toedev *tdev, unsigned int tid)
557 {
558 struct toe_data *td = TOE_DATA(tdev);
559 struct toe_tid_entry *p = &td->tid_maps.tid_tab[tid];
560
561 mtx_lock(&td->tid_release_lock);
562 p->ctx = td->tid_release_list;
563 td->tid_release_list = p;
564
565 if (!p->ctx)
566 workqueue_enqueue(td->tid_release_task.wq, &td->tid_release_task.w, NULL);
567
568 mtx_unlock(&td->tid_release_lock);
569 }
570
571 /*
572 * Remove a tid from the TID table. A client may defer processing its last
573 * CPL message if it is locked at the time it arrives, and while the message
574 * sits in the client's backlog the TID may be reused for another connection.
575 * To handle this we atomically switch the TID association if it still points
576 * to the original client context.
577 */
578 void
cxgb_remove_tid(struct toedev * tdev,void * ctx,unsigned int tid)579 cxgb_remove_tid(struct toedev *tdev, void *ctx, unsigned int tid)
580 {
581 struct tid_info *t = &(TOE_DATA(tdev))->tid_maps;
582
583 BUG_ON(tid >= t->ntids);
584 if (tdev->type == T3A)
585 atomic_cmpset_ptr((uintptr_t *)&t->tid_tab[tid].ctx, (long)NULL, (long)ctx);
586 else {
587 struct mbuf *m;
588
589 m = m_get(M_NOWAIT, MT_DATA);
590 if (__predict_true(m != NULL)) {
591 mk_tid_release(m, tid);
592 cxgb_ofld_send(tdev, m);
593 t->tid_tab[tid].ctx = NULL;
594 } else
595 cxgb_queue_tid_release(tdev, tid);
596 }
597 atomic_add_int(&t->tids_in_use, -1);
598 }
599
600 int
cxgb_alloc_atid(struct toedev * tdev,struct cxgb_client * client,void * ctx)601 cxgb_alloc_atid(struct toedev *tdev, struct cxgb_client *client,
602 void *ctx)
603 {
604 int atid = -1;
605 struct tid_info *t = &(TOE_DATA(tdev))->tid_maps;
606
607 mtx_lock(&t->atid_lock);
608 if (t->afree) {
609 union active_open_entry *p = t->afree;
610
611 atid = (p - t->atid_tab) + t->atid_base;
612 t->afree = p->next;
613 p->toe_tid.ctx = ctx;
614 p->toe_tid.client = client;
615 t->atids_in_use++;
616 }
617 mtx_unlock(&t->atid_lock);
618 return atid;
619 }
620
621 int
cxgb_alloc_stid(struct toedev * tdev,struct cxgb_client * client,void * ctx)622 cxgb_alloc_stid(struct toedev *tdev, struct cxgb_client *client,
623 void *ctx)
624 {
625 int stid = -1;
626 struct tid_info *t = &(TOE_DATA(tdev))->tid_maps;
627
628 mtx_lock(&t->stid_lock);
629 if (t->sfree) {
630 union listen_entry *p = t->sfree;
631
632 stid = (p - t->stid_tab) + t->stid_base;
633 t->sfree = p->next;
634 p->toe_tid.ctx = ctx;
635 p->toe_tid.client = client;
636 t->stids_in_use++;
637 }
638 mtx_unlock(&t->stid_lock);
639 return stid;
640 }
641
642 static int
do_smt_write_rpl(struct toedev * dev,struct mbuf * m)643 do_smt_write_rpl(struct toedev *dev, struct mbuf *m)
644 {
645 struct cpl_smt_write_rpl *rpl = cplhdr(m);
646
647 if (rpl->status != CPL_ERR_NONE)
648 log(LOG_ERR,
649 "Unexpected SMT_WRITE_RPL status %u for entry %u\n",
650 rpl->status, GET_TID(rpl));
651
652 return CPL_RET_BUF_DONE;
653 }
654
655 static int
do_l2t_write_rpl(struct toedev * dev,struct mbuf * m)656 do_l2t_write_rpl(struct toedev *dev, struct mbuf *m)
657 {
658 struct cpl_l2t_write_rpl *rpl = cplhdr(m);
659
660 if (rpl->status != CPL_ERR_NONE)
661 log(LOG_ERR,
662 "Unexpected L2T_WRITE_RPL status %u for entry %u\n",
663 rpl->status, GET_TID(rpl));
664
665 return CPL_RET_BUF_DONE;
666 }
667
668 static int
do_act_open_rpl(struct toedev * dev,struct mbuf * m)669 do_act_open_rpl(struct toedev *dev, struct mbuf *m)
670 {
671 struct cpl_act_open_rpl *rpl = cplhdr(m);
672 unsigned int atid = G_TID(ntohl(rpl->atid));
673 struct toe_tid_entry *toe_tid;
674
675 toe_tid = lookup_atid(&(TOE_DATA(dev))->tid_maps, atid);
676 if (toe_tid->ctx && toe_tid->client && toe_tid->client->handlers &&
677 toe_tid->client->handlers[CPL_ACT_OPEN_RPL]) {
678 return toe_tid->client->handlers[CPL_ACT_OPEN_RPL] (dev, m,
679 toe_tid->ctx);
680 } else {
681 log(LOG_ERR, "%s: received clientless CPL command 0x%x\n",
682 dev->name, CPL_ACT_OPEN_RPL);
683 return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
684 }
685 }
686
687 static int
do_stid_rpl(struct toedev * dev,struct mbuf * m)688 do_stid_rpl(struct toedev *dev, struct mbuf *m)
689 {
690 union opcode_tid *p = cplhdr(m);
691 unsigned int stid = G_TID(ntohl(p->opcode_tid));
692 struct toe_tid_entry *toe_tid;
693
694 toe_tid = lookup_stid(&(TOE_DATA(dev))->tid_maps, stid);
695 if (toe_tid->ctx && toe_tid->client->handlers &&
696 toe_tid->client->handlers[p->opcode]) {
697 return toe_tid->client->handlers[p->opcode] (dev, m, toe_tid->ctx);
698 } else {
699 log(LOG_ERR, "%s: received clientless CPL command 0x%x\n",
700 dev->name, p->opcode);
701 return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
702 }
703 }
704
705 static int
do_hwtid_rpl(struct toedev * dev,struct mbuf * m)706 do_hwtid_rpl(struct toedev *dev, struct mbuf *m)
707 {
708 union opcode_tid *p = cplhdr(m);
709 unsigned int hwtid;
710 struct toe_tid_entry *toe_tid;
711
712 printf("do_hwtid_rpl m=%p\n", m);
713 return (0);
714 #ifdef notyet
715
716 hwtid = G_TID(ntohl(p->opcode_tid));
717
718 toe_tid = lookup_tid(&(TOE_DATA(dev))->tid_maps, hwtid);
719 if (toe_tid->ctx && toe_tid->client->handlers &&
720 toe_tid->client->handlers[p->opcode]) {
721 return toe_tid->client->handlers[p->opcode]
722 (dev, m, toe_tid->ctx);
723 } else {
724 log(LOG_ERR, "%s: received clientless CPL command 0x%x\n",
725 dev->name, p->opcode);
726 return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
727 }
728 #endif
729 }
730
731 static int
do_cr(struct toedev * dev,struct mbuf * m)732 do_cr(struct toedev *dev, struct mbuf *m)
733 {
734 struct cpl_pass_accept_req *req = cplhdr(m);
735 unsigned int stid = G_PASS_OPEN_TID(ntohl(req->tos_tid));
736 struct toe_tid_entry *toe_tid;
737
738 toe_tid = lookup_stid(&(TOE_DATA(dev))->tid_maps, stid);
739 if (toe_tid->ctx && toe_tid->client->handlers &&
740 toe_tid->client->handlers[CPL_PASS_ACCEPT_REQ]) {
741 return toe_tid->client->handlers[CPL_PASS_ACCEPT_REQ]
742 (dev, m, toe_tid->ctx);
743 } else {
744 log(LOG_ERR, "%s: received clientless CPL command 0x%x\n",
745 dev->name, CPL_PASS_ACCEPT_REQ);
746 return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
747 }
748 }
749
750 static int
do_abort_req_rss(struct toedev * dev,struct mbuf * m)751 do_abort_req_rss(struct toedev *dev, struct mbuf *m)
752 {
753 union opcode_tid *p = cplhdr(m);
754 unsigned int hwtid = G_TID(ntohl(p->opcode_tid));
755 struct toe_tid_entry *toe_tid;
756
757 toe_tid = lookup_tid(&(TOE_DATA(dev))->tid_maps, hwtid);
758 if (toe_tid->ctx && toe_tid->client->handlers &&
759 toe_tid->client->handlers[p->opcode]) {
760 return toe_tid->client->handlers[p->opcode]
761 (dev, m, toe_tid->ctx);
762 } else {
763 struct cpl_abort_req_rss *req = cplhdr(m);
764 struct cpl_abort_rpl *rpl;
765
766 struct mbuf *m2 = m_get(M_NOWAIT, MT_DATA);
767 if (!m2) {
768 log(LOG_NOTICE, "do_abort_req_rss: couldn't get mbuf!\n");
769 goto out;
770 }
771
772 m_set_priority(m2, CPL_PRIORITY_DATA);
773 #if 0
774 __skb_put(skb, sizeof(struct cpl_abort_rpl));
775 #endif
776 rpl = cplhdr(m2);
777 rpl->wr.wr_hi =
778 htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_RPL));
779 rpl->wr.wr_lo = htonl(V_WR_TID(GET_TID(req)));
780 OPCODE_TID(rpl) =
781 htonl(MK_OPCODE_TID(CPL_ABORT_RPL, GET_TID(req)));
782 rpl->cmd = req->status;
783 cxgb_ofld_send(dev, m2);
784 out:
785 return CPL_RET_BUF_DONE;
786 }
787 }
788
789 static int
do_act_establish(struct toedev * dev,struct mbuf * m)790 do_act_establish(struct toedev *dev, struct mbuf *m)
791 {
792 struct cpl_act_establish *req = cplhdr(m);
793 unsigned int atid = G_PASS_OPEN_TID(ntohl(req->tos_tid));
794 struct toe_tid_entry *toe_tid;
795
796 toe_tid = lookup_atid(&(TOE_DATA(dev))->tid_maps, atid);
797 if (toe_tid->ctx && toe_tid->client->handlers &&
798 toe_tid->client->handlers[CPL_ACT_ESTABLISH]) {
799 return toe_tid->client->handlers[CPL_ACT_ESTABLISH]
800 (dev, m, toe_tid->ctx);
801 } else {
802 log(LOG_ERR, "%s: received clientless CPL command 0x%x\n",
803 dev->name, CPL_PASS_ACCEPT_REQ);
804 return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
805 }
806 }
807
808 static int
do_set_tcb_rpl(struct toedev * dev,struct mbuf * m)809 do_set_tcb_rpl(struct toedev *dev, struct mbuf *m)
810 {
811 struct cpl_set_tcb_rpl *rpl = cplhdr(m);
812
813 if (rpl->status != CPL_ERR_NONE)
814 log(LOG_ERR,
815 "Unexpected SET_TCB_RPL status %u for tid %u\n",
816 rpl->status, GET_TID(rpl));
817 return CPL_RET_BUF_DONE;
818 }
819
820 static int
do_trace(struct toedev * dev,struct mbuf * m)821 do_trace(struct toedev *dev, struct mbuf *m)
822 {
823 #if 0
824 struct cpl_trace_pkt *p = cplhdr(m);
825
826
827 skb->protocol = 0xffff;
828 skb->dev = dev->lldev;
829 skb_pull(skb, sizeof(*p));
830 skb->mac.raw = mtod(m, (char *));
831 netif_receive_skb(skb);
832 #endif
833 return 0;
834 }
835
836 static int
do_term(struct toedev * dev,struct mbuf * m)837 do_term(struct toedev *dev, struct mbuf *m)
838 {
839 unsigned int hwtid = ntohl(m_get_priority(m)) >> 8 & 0xfffff;
840 unsigned int opcode = G_OPCODE(ntohl(m->m_pkthdr.csum_data));
841 struct toe_tid_entry *toe_tid;
842
843 toe_tid = lookup_tid(&(TOE_DATA(dev))->tid_maps, hwtid);
844 if (toe_tid->ctx && toe_tid->client->handlers &&
845 toe_tid->client->handlers[opcode]) {
846 return toe_tid->client->handlers[opcode](dev, m, toe_tid->ctx);
847 } else {
848 log(LOG_ERR, "%s: received clientless CPL command 0x%x\n",
849 dev->name, opcode);
850 return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
851 }
852 return (0);
853 }
854
855 #if defined(FOO)
856 #include <linux/config.h>
857 #include <linux/kallsyms.h>
858 #include <linux/kprobes.h>
859 #include <net/arp.h>
860
861 static int (*orig_arp_constructor)(struct ifnet *);
862
863 static void
neigh_suspect(struct ifnet * neigh)864 neigh_suspect(struct ifnet *neigh)
865 {
866 struct hh_cache *hh;
867
868 neigh->output = neigh->ops->output;
869
870 for (hh = neigh->hh; hh; hh = hh->hh_next)
871 hh->hh_output = neigh->ops->output;
872 }
873
874 static void
neigh_connect(struct ifnet * neigh)875 neigh_connect(struct ifnet *neigh)
876 {
877 struct hh_cache *hh;
878
879 neigh->output = neigh->ops->connected_output;
880
881 for (hh = neigh->hh; hh; hh = hh->hh_next)
882 hh->hh_output = neigh->ops->hh_output;
883 }
884
885 static inline int
neigh_max_probes(const struct neighbour * n)886 neigh_max_probes(const struct neighbour *n)
887 {
888 const struct neigh_parms *p = n->parms;
889 return (n->nud_state & NUD_PROBE ?
890 p->ucast_probes :
891 p->ucast_probes + p->app_probes + p->mcast_probes);
892 }
893
894 static void
neigh_timer_handler_offload(unsigned long arg)895 neigh_timer_handler_offload(unsigned long arg)
896 {
897 unsigned long now, next;
898 struct neighbour *neigh = (struct neighbour *)arg;
899 unsigned state;
900 int notify = 0;
901
902 write_lock(&neigh->lock);
903
904 state = neigh->nud_state;
905 now = jiffies;
906 next = now + HZ;
907
908 if (!(state & NUD_IN_TIMER)) {
909 #ifndef CONFIG_SMP
910 log(LOG_WARNING, "neigh: timer & !nud_in_timer\n");
911 #endif
912 goto out;
913 }
914
915 if (state & NUD_REACHABLE) {
916 if (time_before_eq(now,
917 neigh->confirmed +
918 neigh->parms->reachable_time)) {
919 next = neigh->confirmed + neigh->parms->reachable_time;
920 } else if (time_before_eq(now,
921 neigh->used +
922 neigh->parms->delay_probe_time)) {
923 neigh->nud_state = NUD_DELAY;
924 neigh->updated = jiffies;
925 neigh_suspect(neigh);
926 next = now + neigh->parms->delay_probe_time;
927 } else {
928 neigh->nud_state = NUD_STALE;
929 neigh->updated = jiffies;
930 neigh_suspect(neigh);
931 cxgb_neigh_update(neigh);
932 }
933 } else if (state & NUD_DELAY) {
934 if (time_before_eq(now,
935 neigh->confirmed +
936 neigh->parms->delay_probe_time)) {
937 neigh->nud_state = NUD_REACHABLE;
938 neigh->updated = jiffies;
939 neigh_connect(neigh);
940 cxgb_neigh_update(neigh);
941 next = neigh->confirmed + neigh->parms->reachable_time;
942 } else {
943 neigh->nud_state = NUD_PROBE;
944 neigh->updated = jiffies;
945 atomic_set_int(&neigh->probes, 0);
946 next = now + neigh->parms->retrans_time;
947 }
948 } else {
949 /* NUD_PROBE|NUD_INCOMPLETE */
950 next = now + neigh->parms->retrans_time;
951 }
952 /*
953 * Needed for read of probes
954 */
955 mb();
956 if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) &&
957 neigh->probes >= neigh_max_probes(neigh)) {
958 struct mbuf *m;
959
960 neigh->nud_state = NUD_FAILED;
961 neigh->updated = jiffies;
962 notify = 1;
963 cxgb_neigh_update(neigh);
964 NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
965
966 /* It is very thin place. report_unreachable is very
967 complicated routine. Particularly, it can hit the same
968 neighbour entry!
969 So that, we try to be accurate and avoid dead loop. --ANK
970 */
971 while (neigh->nud_state == NUD_FAILED &&
972 (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) {
973 write_unlock(&neigh->lock);
974 neigh->ops->error_report(neigh, skb);
975 write_lock(&neigh->lock);
976 }
977 skb_queue_purge(&neigh->arp_queue);
978 }
979
980 if (neigh->nud_state & NUD_IN_TIMER) {
981 if (time_before(next, jiffies + HZ/2))
982 next = jiffies + HZ/2;
983 if (!mod_timer(&neigh->timer, next))
984 neigh_hold(neigh);
985 }
986 if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) {
987 struct mbuf *m = skb_peek(&neigh->arp_queue);
988
989 write_unlock(&neigh->lock);
990 neigh->ops->solicit(neigh, skb);
991 atomic_add_int(&neigh->probes, 1);
992 if (m)
993 m_free(m);
994 } else {
995 out:
996 write_unlock(&neigh->lock);
997 }
998
999 #ifdef CONFIG_ARPD
1000 if (notify && neigh->parms->app_probes)
1001 neigh_app_notify(neigh);
1002 #endif
1003 neigh_release(neigh);
1004 }
1005
1006 static int
arp_constructor_offload(struct neighbour * neigh)1007 arp_constructor_offload(struct neighbour *neigh)
1008 {
1009 if (neigh->ifp && is_offloading(neigh->ifp))
1010 neigh->timer.function = neigh_timer_handler_offload;
1011 return orig_arp_constructor(neigh);
1012 }
1013
1014 /*
1015 * This must match exactly the signature of neigh_update for jprobes to work.
1016 * It runs from a trap handler with interrupts off so don't disable BH.
1017 */
1018 static int
neigh_update_offload(struct neighbour * neigh,const u8 * lladdr,u8 new,u32 flags)1019 neigh_update_offload(struct neighbour *neigh, const u8 *lladdr,
1020 u8 new, u32 flags)
1021 {
1022 write_lock(&neigh->lock);
1023 cxgb_neigh_update(neigh);
1024 write_unlock(&neigh->lock);
1025 jprobe_return();
1026 /* NOTREACHED */
1027 return 0;
1028 }
1029
1030 static struct jprobe neigh_update_jprobe = {
1031 .entry = (kprobe_opcode_t *) neigh_update_offload,
1032 .kp.addr = (kprobe_opcode_t *) neigh_update
1033 };
1034
1035 #ifdef MODULE_SUPPORT
1036 static int
prepare_arp_with_t3core(void)1037 prepare_arp_with_t3core(void)
1038 {
1039 int err;
1040
1041 err = register_jprobe(&neigh_update_jprobe);
1042 if (err) {
1043 log(LOG_ERR, "Could not install neigh_update jprobe, "
1044 "error %d\n", err);
1045 return err;
1046 }
1047
1048 orig_arp_constructor = arp_tbl.constructor;
1049 arp_tbl.constructor = arp_constructor_offload;
1050
1051 return 0;
1052 }
1053
1054 static void
restore_arp_sans_t3core(void)1055 restore_arp_sans_t3core(void)
1056 {
1057 arp_tbl.constructor = orig_arp_constructor;
1058 unregister_jprobe(&neigh_update_jprobe);
1059 }
1060
1061 #else /* Module support */
1062 static inline int
prepare_arp_with_t3core(void)1063 prepare_arp_with_t3core(void)
1064 {
1065 return 0;
1066 }
1067
1068 static inline void
restore_arp_sans_t3core(void)1069 restore_arp_sans_t3core(void)
1070 {}
1071 #endif
1072 #endif
1073 /*
1074 * Process a received packet with an unknown/unexpected CPL opcode.
1075 */
1076 static int
do_bad_cpl(struct toedev * dev,struct mbuf * m)1077 do_bad_cpl(struct toedev *dev, struct mbuf *m)
1078 {
1079 log(LOG_ERR, "%s: received bad CPL command 0x%x\n", dev->name,
1080 *mtod(m, uint32_t *));
1081 return (CPL_RET_BUF_DONE | CPL_RET_BAD_MSG);
1082 }
1083
1084 /*
1085 * Handlers for each CPL opcode
1086 */
1087 static cpl_handler_func cpl_handlers[NUM_CPL_CMDS];
1088
1089 /*
1090 * Add a new handler to the CPL dispatch table. A NULL handler may be supplied
1091 * to unregister an existing handler.
1092 */
1093 void
t3_register_cpl_handler(unsigned int opcode,cpl_handler_func h)1094 t3_register_cpl_handler(unsigned int opcode, cpl_handler_func h)
1095 {
1096 if (opcode < NUM_CPL_CMDS)
1097 cpl_handlers[opcode] = h ? h : do_bad_cpl;
1098 else
1099 log(LOG_ERR, "T3C: handler registration for "
1100 "opcode %x failed\n", opcode);
1101 }
1102
1103 /*
1104 * TOEDEV's receive method.
1105 */
1106 int
process_rx(struct toedev * dev,struct mbuf ** m,int n)1107 process_rx(struct toedev *dev, struct mbuf **m, int n)
1108 {
1109 while (n--) {
1110 struct mbuf *m0 = *m++;
1111 unsigned int opcode = G_OPCODE(ntohl(m0->m_pkthdr.csum_data));
1112 int ret = cpl_handlers[opcode] (dev, m0);
1113
1114 #if VALIDATE_TID
1115 if (ret & CPL_RET_UNKNOWN_TID) {
1116 union opcode_tid *p = cplhdr(m0);
1117
1118 log(LOG_ERR, "%s: CPL message (opcode %u) had "
1119 "unknown TID %u\n", dev->name, opcode,
1120 G_TID(ntohl(p->opcode_tid)));
1121 }
1122 #endif
1123 if (ret & CPL_RET_BUF_DONE)
1124 m_freem(m0);
1125 }
1126 return 0;
1127 }
1128
1129 /*
1130 * Sends an sk_buff to a T3C driver after dealing with any active network taps.
1131 */
1132 int
cxgb_ofld_send(struct toedev * dev,struct mbuf * m)1133 cxgb_ofld_send(struct toedev *dev, struct mbuf *m)
1134 {
1135 int r;
1136
1137 critical_enter();
1138 r = dev->send(dev, m);
1139 critical_exit();
1140 return r;
1141 }
1142
1143
1144 /**
1145 * cxgb_ofld_recv - process n received offload packets
1146 * @dev: the offload device
1147 * @m: an array of offload packets
1148 * @n: the number of offload packets
1149 *
1150 * Process an array of ingress offload packets. Each packet is forwarded
1151 * to any active network taps and then passed to the offload device's receive
1152 * method. We optimize passing packets to the receive method by passing
1153 * it the whole array at once except when there are active taps.
1154 */
1155 int
cxgb_ofld_recv(struct toedev * dev,struct mbuf ** m,int n)1156 cxgb_ofld_recv(struct toedev *dev, struct mbuf **m, int n)
1157 {
1158
1159 #if defined(CONFIG_CHELSIO_T3)
1160 if (likely(!netdev_nit))
1161 return dev->recv(dev, skb, n);
1162
1163 for ( ; n; n--, skb++) {
1164 skb[0]->dev = dev->lldev;
1165 dev_queue_xmit_nit(skb[0], dev->lldev);
1166 skb[0]->dev = NULL;
1167 dev->recv(dev, skb, 1);
1168 }
1169 return 0;
1170 #else
1171 return dev->recv(dev, m, n);
1172 #endif
1173 }
1174
1175 void
cxgb_neigh_update(struct rtentry * rt)1176 cxgb_neigh_update(struct rtentry *rt)
1177 {
1178
1179 if (is_offloading(rt->rt_ifp)) {
1180 struct toedev *tdev = TOEDEV(rt->rt_ifp);
1181
1182 BUG_ON(!tdev);
1183 t3_l2t_update(tdev, rt);
1184 }
1185 }
1186
1187 static void
set_l2t_ix(struct toedev * tdev,u32 tid,struct l2t_entry * e)1188 set_l2t_ix(struct toedev *tdev, u32 tid, struct l2t_entry *e)
1189 {
1190 struct mbuf *m;
1191 struct cpl_set_tcb_field *req;
1192
1193 m = m_gethdr(M_NOWAIT, MT_DATA);
1194 if (!m) {
1195 log(LOG_ERR, "%s: cannot allocate mbuf!\n", __func__);
1196 return;
1197 }
1198
1199 m_set_priority(m, CPL_PRIORITY_CONTROL);
1200 req = mtod(m, struct cpl_set_tcb_field *);
1201 req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
1202 OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
1203 req->reply = 0;
1204 req->cpu_idx = 0;
1205 req->word = htons(W_TCB_L2T_IX);
1206 req->mask = htobe64(V_TCB_L2T_IX(M_TCB_L2T_IX));
1207 req->val = htobe64(V_TCB_L2T_IX(e->idx));
1208 tdev->send(tdev, m);
1209 }
1210
1211 void
cxgb_redirect(struct rtentry * old,struct rtentry * new)1212 cxgb_redirect(struct rtentry *old, struct rtentry *new)
1213 {
1214 struct ifnet *olddev, *newdev;
1215 struct tid_info *ti;
1216 struct toedev *tdev;
1217 u32 tid;
1218 int update_tcb;
1219 struct l2t_entry *e;
1220 struct toe_tid_entry *te;
1221
1222 olddev = old->rt_ifp;
1223 newdev = new->rt_ifp;
1224 if (!is_offloading(olddev))
1225 return;
1226 if (!is_offloading(newdev)) {
1227 log(LOG_WARNING, "%s: Redirect to non-offload"
1228 "device ignored.\n", __func__);
1229 return;
1230 }
1231 tdev = TOEDEV(olddev);
1232 BUG_ON(!tdev);
1233 if (tdev != TOEDEV(newdev)) {
1234 log(LOG_WARNING, "%s: Redirect to different "
1235 "offload device ignored.\n", __func__);
1236 return;
1237 }
1238
1239 /* Add new L2T entry */
1240 e = t3_l2t_get(tdev, new, ((struct port_info *)new->rt_ifp->if_softc)->port_id);
1241 if (!e) {
1242 log(LOG_ERR, "%s: couldn't allocate new l2t entry!\n",
1243 __func__);
1244 return;
1245 }
1246
1247 /* Walk tid table and notify clients of dst change. */
1248 ti = &(TOE_DATA(tdev))->tid_maps;
1249 for (tid=0; tid < ti->ntids; tid++) {
1250 te = lookup_tid(ti, tid);
1251 BUG_ON(!te);
1252 if (te->ctx && te->client && te->client->redirect) {
1253 update_tcb = te->client->redirect(te->ctx, old, new,
1254 e);
1255 if (update_tcb) {
1256 l2t_hold(L2DATA(tdev), e);
1257 set_l2t_ix(tdev, tid, e);
1258 }
1259 }
1260 }
1261 l2t_release(L2DATA(tdev), e);
1262 }
1263
1264 /*
1265 * Allocate a chunk of memory using kmalloc or, if that fails, vmalloc.
1266 * The allocated memory is cleared.
1267 */
1268 void *
cxgb_alloc_mem(unsigned long size)1269 cxgb_alloc_mem(unsigned long size)
1270 {
1271 return malloc(size, M_DEVBUF, M_ZERO);
1272 }
1273
1274 /*
1275 * Free memory allocated through t3_alloc_mem().
1276 */
1277 void
cxgb_free_mem(void * addr)1278 cxgb_free_mem(void *addr)
1279 {
1280 free(addr, M_DEVBUF);
1281 }
1282
1283
1284 /*
1285 * Allocate and initialize the TID tables. Returns 0 on success.
1286 */
1287 static int
init_tid_tabs(struct tid_info * t,unsigned int ntids,unsigned int natids,unsigned int nstids,unsigned int atid_base,unsigned int stid_base)1288 init_tid_tabs(struct tid_info *t, unsigned int ntids,
1289 unsigned int natids, unsigned int nstids,
1290 unsigned int atid_base, unsigned int stid_base)
1291 {
1292 unsigned long size = ntids * sizeof(*t->tid_tab) +
1293 natids * sizeof(*t->atid_tab) + nstids * sizeof(*t->stid_tab);
1294
1295 t->tid_tab = cxgb_alloc_mem(size);
1296 if (!t->tid_tab)
1297 return (ENOMEM);
1298
1299 t->stid_tab = (union listen_entry *)&t->tid_tab[ntids];
1300 t->atid_tab = (union active_open_entry *)&t->stid_tab[nstids];
1301 t->ntids = ntids;
1302 t->nstids = nstids;
1303 t->stid_base = stid_base;
1304 t->sfree = NULL;
1305 t->natids = natids;
1306 t->atid_base = atid_base;
1307 t->afree = NULL;
1308 t->stids_in_use = t->atids_in_use = 0;
1309 atomic_set_int(&t->tids_in_use, 0);
1310 mtx_init(&t->stid_lock, "stid", NULL, MTX_DEF);
1311 mtx_init(&t->atid_lock, "atid", NULL, MTX_DEF);
1312
1313 /*
1314 * Setup the free lists for stid_tab and atid_tab.
1315 */
1316 if (nstids) {
1317 while (--nstids)
1318 t->stid_tab[nstids - 1].next = &t->stid_tab[nstids];
1319 t->sfree = t->stid_tab;
1320 }
1321 if (natids) {
1322 while (--natids)
1323 t->atid_tab[natids - 1].next = &t->atid_tab[natids];
1324 t->afree = t->atid_tab;
1325 }
1326 return 0;
1327 }
1328
1329 static void
free_tid_maps(struct tid_info * t)1330 free_tid_maps(struct tid_info *t)
1331 {
1332 cxgb_free_mem(t->tid_tab);
1333 }
1334
1335 static inline void
add_adapter(adapter_t * adap)1336 add_adapter(adapter_t *adap)
1337 {
1338 rw_wlock(&adapter_list_lock);
1339 TAILQ_INSERT_TAIL(&adapter_list, adap, adapter_entry);
1340 rw_wunlock(&adapter_list_lock);
1341 }
1342
1343 static inline void
remove_adapter(adapter_t * adap)1344 remove_adapter(adapter_t *adap)
1345 {
1346 rw_wlock(&adapter_list_lock);
1347 TAILQ_REMOVE(&adapter_list, adap, adapter_entry);
1348 rw_wunlock(&adapter_list_lock);
1349 }
1350
1351 /*
1352 * XXX
1353 */
1354 #define t3_free_l2t(...)
1355
1356 int
cxgb_offload_activate(struct adapter * adapter)1357 cxgb_offload_activate(struct adapter *adapter)
1358 {
1359 struct toedev *dev = &adapter->tdev;
1360 int natids, err;
1361 struct toe_data *t;
1362 struct tid_range stid_range, tid_range;
1363 struct mtutab mtutab;
1364 unsigned int l2t_capacity;
1365
1366 t = malloc(sizeof(*t), M_DEVBUF, M_WAITOK);
1367 if (!t)
1368 return (ENOMEM);
1369
1370 err = (EOPNOTSUPP);
1371 if (dev->ctl(dev, GET_TX_MAX_CHUNK, &t->tx_max_chunk) < 0 ||
1372 dev->ctl(dev, GET_MAX_OUTSTANDING_WR, &t->max_wrs) < 0 ||
1373 dev->ctl(dev, GET_L2T_CAPACITY, &l2t_capacity) < 0 ||
1374 dev->ctl(dev, GET_MTUS, &mtutab) < 0 ||
1375 dev->ctl(dev, GET_TID_RANGE, &tid_range) < 0 ||
1376 dev->ctl(dev, GET_STID_RANGE, &stid_range) < 0)
1377 goto out_free;
1378
1379 err = (ENOMEM);
1380 L2DATA(dev) = t3_init_l2t(l2t_capacity);
1381 if (!L2DATA(dev))
1382 goto out_free;
1383
1384 natids = uimin(tid_range.num / 2, MAX_ATIDS);
1385 err = init_tid_tabs(&t->tid_maps, tid_range.num, natids,
1386 stid_range.num, ATID_BASE, stid_range.base);
1387 if (err)
1388 goto out_free_l2t;
1389
1390 t->mtus = mtutab.mtus;
1391 t->nmtus = mtutab.size;
1392
1393 t->tid_release_task.name = "t3_process_tid_release_list";
1394 t->tid_release_task.func = t3_process_tid_release_list;
1395 t->tid_release_task.context = adapter;
1396 kthread_create(PRI_NONE, 0, NULL, cxgb_make_task, &t->tid_release_task, NULL, "cxgb_make_task");
1397 mtx_init(&t->tid_release_lock, "tid release", NULL, MTX_DEF);
1398 t->dev = dev;
1399
1400 TOE_DATA(dev) = t;
1401 dev->recv = process_rx;
1402 dev->neigh_update = t3_l2t_update;
1403 #if 0
1404 offload_proc_dev_setup(dev);
1405 #endif
1406 /* Register netevent handler once */
1407 if (TAILQ_EMPTY(&adapter_list)) {
1408 #if defined(CONFIG_CHELSIO_T3_MODULE)
1409 if (prepare_arp_with_t3core())
1410 log(LOG_ERR, "Unable to set offload capabilities\n");
1411 #endif
1412 }
1413 add_adapter(adapter);
1414 return 0;
1415
1416 out_free_l2t:
1417 t3_free_l2t(L2DATA(dev));
1418 L2DATA(dev) = NULL;
1419 out_free:
1420 free(t, M_DEVBUF);
1421 return err;
1422
1423 }
1424
1425 void
cxgb_offload_deactivate(struct adapter * adapter)1426 cxgb_offload_deactivate(struct adapter *adapter)
1427 {
1428 struct toedev *tdev = &adapter->tdev;
1429 struct toe_data *t = TOE_DATA(tdev);
1430
1431 remove_adapter(adapter);
1432 if (TAILQ_EMPTY(&adapter_list)) {
1433 #if defined(CONFIG_CHELSIO_T3_MODULE)
1434 restore_arp_sans_t3core();
1435 #endif
1436 }
1437 free_tid_maps(&t->tid_maps);
1438 TOE_DATA(tdev) = NULL;
1439 t3_free_l2t(L2DATA(tdev));
1440 L2DATA(tdev) = NULL;
1441 free(t, M_DEVBUF);
1442 }
1443
1444
1445 static inline void
register_tdev(struct toedev * tdev)1446 register_tdev(struct toedev *tdev)
1447 {
1448 static int unit;
1449
1450 mtx_lock(&cxgb_db_lock);
1451 snprintf(tdev->name, sizeof(tdev->name), "ofld_dev%d", unit++);
1452 TAILQ_INSERT_TAIL(&ofld_dev_list, tdev, ofld_entry);
1453 mtx_unlock(&cxgb_db_lock);
1454 }
1455
1456 static inline void
unregister_tdev(struct toedev * tdev)1457 unregister_tdev(struct toedev *tdev)
1458 {
1459 mtx_lock(&cxgb_db_lock);
1460 TAILQ_REMOVE(&ofld_dev_list, tdev, ofld_entry);
1461 mtx_unlock(&cxgb_db_lock);
1462 }
1463
1464 void
cxgb_adapter_ofld(struct adapter * adapter)1465 cxgb_adapter_ofld(struct adapter *adapter)
1466 {
1467 struct toedev *tdev = &adapter->tdev;
1468
1469 cxgb_set_dummy_ops(tdev);
1470 tdev->send = t3_offload_tx;
1471 tdev->ctl = cxgb_offload_ctl;
1472 tdev->type = adapter->params.rev == 0 ?
1473 T3A : T3B;
1474
1475 register_tdev(tdev);
1476 #if 0
1477 offload_proc_dev_init(tdev);
1478 #endif
1479 }
1480
1481 void
cxgb_adapter_unofld(struct adapter * adapter)1482 cxgb_adapter_unofld(struct adapter *adapter)
1483 {
1484 struct toedev *tdev = &adapter->tdev;
1485 #if 0
1486 offload_proc_dev_cleanup(tdev);
1487 offload_proc_dev_exit(tdev);
1488 #endif
1489 tdev->recv = NULL;
1490 tdev->neigh_update = NULL;
1491
1492 unregister_tdev(tdev);
1493 }
1494
1495 void
cxgb_offload_init(void)1496 cxgb_offload_init(void)
1497 {
1498 int i;
1499
1500 if (inited)
1501 return;
1502 else
1503 inited = 1;
1504
1505 mtx_init(&cxgb_db_lock, "ofld db", NULL, MTX_DEF);
1506 rw_init(&adapter_list_lock);
1507 TAILQ_INIT(&client_list);
1508 TAILQ_INIT(&ofld_dev_list);
1509 TAILQ_INIT(&adapter_list);
1510
1511 for (i = 0; i < NUM_CPL_CMDS; ++i)
1512 cpl_handlers[i] = do_bad_cpl;
1513
1514 t3_register_cpl_handler(CPL_SMT_WRITE_RPL, do_smt_write_rpl);
1515 t3_register_cpl_handler(CPL_L2T_WRITE_RPL, do_l2t_write_rpl);
1516 t3_register_cpl_handler(CPL_PASS_OPEN_RPL, do_stid_rpl);
1517 t3_register_cpl_handler(CPL_CLOSE_LISTSRV_RPL, do_stid_rpl);
1518 t3_register_cpl_handler(CPL_PASS_ACCEPT_REQ, do_cr);
1519 t3_register_cpl_handler(CPL_PASS_ESTABLISH, do_hwtid_rpl);
1520 t3_register_cpl_handler(CPL_ABORT_RPL_RSS, do_hwtid_rpl);
1521 t3_register_cpl_handler(CPL_ABORT_RPL, do_hwtid_rpl);
1522 t3_register_cpl_handler(CPL_RX_URG_NOTIFY, do_hwtid_rpl);
1523 t3_register_cpl_handler(CPL_RX_DATA, do_hwtid_rpl);
1524 t3_register_cpl_handler(CPL_TX_DATA_ACK, do_hwtid_rpl);
1525 t3_register_cpl_handler(CPL_TX_DMA_ACK, do_hwtid_rpl);
1526 t3_register_cpl_handler(CPL_ACT_OPEN_RPL, do_act_open_rpl);
1527 t3_register_cpl_handler(CPL_PEER_CLOSE, do_hwtid_rpl);
1528 t3_register_cpl_handler(CPL_CLOSE_CON_RPL, do_hwtid_rpl);
1529 t3_register_cpl_handler(CPL_ABORT_REQ_RSS, do_abort_req_rss);
1530 t3_register_cpl_handler(CPL_ACT_ESTABLISH, do_act_establish);
1531 t3_register_cpl_handler(CPL_SET_TCB_RPL, do_set_tcb_rpl);
1532 t3_register_cpl_handler(CPL_RDMA_TERMINATE, do_term);
1533 t3_register_cpl_handler(CPL_RDMA_EC_STATUS, do_hwtid_rpl);
1534 t3_register_cpl_handler(CPL_TRACE_PKT, do_trace);
1535 t3_register_cpl_handler(CPL_RX_DATA_DDP, do_hwtid_rpl);
1536 t3_register_cpl_handler(CPL_RX_DDP_COMPLETE, do_hwtid_rpl);
1537 t3_register_cpl_handler(CPL_ISCSI_HDR, do_hwtid_rpl);
1538 #if 0
1539 if (offload_proc_init())
1540 log(LOG_WARNING, "Unable to create /proc/net/cxgb3 dir\n");
1541 #endif
1542 }
1543
1544 void
cxgb_offload_exit(void)1545 cxgb_offload_exit(void)
1546 {
1547 static int deinited = 0;
1548
1549 if (deinited)
1550 return;
1551
1552 deinited = 1;
1553 mtx_destroy(&cxgb_db_lock);
1554 rw_destroy(&adapter_list_lock);
1555 #if 0
1556 offload_proc_cleanup();
1557 #endif
1558 }
1559
1560 #if 0
1561 static int
1562 offload_info_read_proc(char *buf, char **start, off_t offset,
1563 int length, int *eof, void *data)
1564 {
1565 struct toe_data *d = data;
1566 struct tid_info *t = &d->tid_maps;
1567 int len;
1568
1569 len = snprintf(buf, length, "TID range: 0..%d, in use: %u\n"
1570 "STID range: %d..%d, in use: %u\n"
1571 "ATID range: %d..%d, in use: %u\n"
1572 "MSS: %u\n",
1573 t->ntids - 1, atomic_read(&t->tids_in_use), t->stid_base,
1574 t->stid_base + t->nstids - 1, t->stids_in_use,
1575 t->atid_base, t->atid_base + t->natids - 1,
1576 t->atids_in_use, d->tx_max_chunk);
1577 if (len > length)
1578 len = length;
1579 *eof = 1;
1580 return len;
1581 }
1582
1583 static int
1584 offload_info_proc_setup(struct proc_dir_entry *dir,
1585 struct toe_data *d)
1586 {
1587 struct proc_dir_entry *p;
1588
1589 if (!dir)
1590 return (EINVAL);
1591
1592 p = create_proc_read_entry("info", 0, dir, offload_info_read_proc, d);
1593 if (!p)
1594 return (ENOMEM);
1595
1596 p->owner = THIS_MODULE;
1597 return 0;
1598 }
1599
1600
1601 static int
1602 offload_devices_read_proc(char *buf, char **start, off_t offset,
1603 int length, int *eof, void *data)
1604 {
1605 int len;
1606 struct toedev *dev;
1607 struct net_device *ndev;
1608
1609 len = snprintf(buf, length, "Device Interfaces\n");
1610
1611 mtx_lock(&cxgb_db_lock);
1612 TAILQ_FOREACH(dev, &ofld_dev_list, ofld_entry) {
1613 if (len >= length)
1614 break;
1615 len += snprintf(buf + len, length - len, "%-16s", dev->name);
1616 read_lock(&dev_base_lock);
1617 for (ndev = dev_base; ndev; ndev = ndev->next) {
1618 if (TOEDEV(ndev) == dev) {
1619 if (len >= length)
1620 break;
1621 len += snprintf(buf + len, length - len, " %s", ndev->name);
1622 }
1623 }
1624 read_unlock(&dev_base_lock);
1625 if (len >= length)
1626 break;
1627 len += snprintf(buf + len, length - len, "\n");
1628 }
1629 mtx_unlock(&cxgb_db_lock);
1630
1631 if (len > length)
1632 len = length;
1633 *eof = 1;
1634 return len;
1635 }
1636
1637 #endif
1638
1639