2 * cxgb4_uld.c:Chelsio Upper Layer Driver Interface for T4/T5/T6 SGE management
4 * Copyright (c) 2016 Chelsio Communications, Inc. All rights reserved.
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 * Written by: Atul Gupta (atul.gupta@chelsio.com)
35 * Written by: Hariprasad Shenai (hariprasad@chelsio.com)
38 #include <linux/kernel.h>
39 #include <linux/module.h>
40 #include <linux/errno.h>
41 #include <linux/types.h>
42 #include <linux/debugfs.h>
43 #include <linux/export.h>
44 #include <linux/list.h>
45 #include <linux/skbuff.h>
46 #include <linux/pci.h>
49 #include "cxgb4_uld.h"
54 #define for_each_uldrxq(m, i) for (i = 0; i < ((m)->nrxq + (m)->nciq); i++)
56 static int get_msix_idx_from_bmap(struct adapter
*adap
)
58 struct uld_msix_bmap
*bmap
= &adap
->msix_bmap_ulds
;
60 unsigned int msix_idx
;
62 spin_lock_irqsave(&bmap
->lock
, flags
);
63 msix_idx
= find_first_zero_bit(bmap
->msix_bmap
, bmap
->mapsize
);
64 if (msix_idx
< bmap
->mapsize
) {
65 __set_bit(msix_idx
, bmap
->msix_bmap
);
67 spin_unlock_irqrestore(&bmap
->lock
, flags
);
71 spin_unlock_irqrestore(&bmap
->lock
, flags
);
75 static void free_msix_idx_in_bmap(struct adapter
*adap
, unsigned int msix_idx
)
77 struct uld_msix_bmap
*bmap
= &adap
->msix_bmap_ulds
;
80 spin_lock_irqsave(&bmap
->lock
, flags
);
81 __clear_bit(msix_idx
, bmap
->msix_bmap
);
82 spin_unlock_irqrestore(&bmap
->lock
, flags
);
85 static int uldrx_handler(struct sge_rspq
*q
, const __be64
*rsp
,
86 const struct pkt_gl
*gl
)
88 struct adapter
*adap
= q
->adap
;
89 struct sge_ofld_rxq
*rxq
= container_of(q
, struct sge_ofld_rxq
, rspq
);
92 /* FW can send CPLs encapsulated in a CPL_FW4_MSG */
93 if (((const struct rss_header
*)rsp
)->opcode
== CPL_FW4_MSG
&&
94 ((const struct cpl_fw4_msg
*)(rsp
+ 1))->type
== FW_TYPE_RSSCPL
)
98 ret
= adap
->uld
[q
->uld
].lro_rx_handler(adap
->uld
[q
->uld
].handle
,
102 ret
= adap
->uld
[q
->uld
].rx_handler(adap
->uld
[q
->uld
].handle
,
112 else if (gl
== CXGB4_MSG_AN
)
119 static int alloc_uld_rxqs(struct adapter
*adap
,
120 struct sge_uld_rxq_info
*rxq_info
,
121 unsigned int nq
, unsigned int offset
, bool lro
)
123 struct sge
*s
= &adap
->sge
;
124 struct sge_ofld_rxq
*q
= rxq_info
->uldrxq
+ offset
;
125 unsigned short *ids
= rxq_info
->rspq_id
+ offset
;
126 unsigned int per_chan
= nq
/ adap
->params
.nports
;
127 unsigned int msi_idx
, bmap_idx
;
130 if (adap
->flags
& USING_MSIX
)
133 msi_idx
= -((int)s
->intrq
.abs_id
+ 1);
135 for (i
= 0; i
< nq
; i
++, q
++) {
137 bmap_idx
= get_msix_idx_from_bmap(adap
);
140 err
= t4_sge_alloc_rxq(adap
, &q
->rspq
, false,
141 adap
->port
[i
/ per_chan
],
143 q
->fl
.size
? &q
->fl
: NULL
,
150 rxq_info
->msix_tbl
[i
+ offset
] = bmap_idx
;
151 memset(&q
->stats
, 0, sizeof(q
->stats
));
153 ids
[i
] = q
->rspq
.abs_id
;
157 q
= rxq_info
->uldrxq
+ offset
;
158 for ( ; i
; i
--, q
++) {
160 free_rspq_fl(adap
, &q
->rspq
,
161 q
->fl
.size
? &q
->fl
: NULL
);
165 /* We need to free rxq also in case of ciq allocation failure */
167 q
= rxq_info
->uldrxq
+ offset
;
168 for ( ; i
; i
--, q
++) {
170 free_rspq_fl(adap
, &q
->rspq
,
171 q
->fl
.size
? &q
->fl
: NULL
);
178 int setup_sge_queues_uld(struct adapter
*adap
, unsigned int uld_type
, bool lro
)
180 struct sge_uld_rxq_info
*rxq_info
= adap
->sge
.uld_rxq_info
[uld_type
];
182 if (adap
->flags
& USING_MSIX
) {
183 rxq_info
->msix_tbl
= kzalloc(rxq_info
->nrxq
+ rxq_info
->nciq
,
185 if (!rxq_info
->msix_tbl
)
189 return !(!alloc_uld_rxqs(adap
, rxq_info
, rxq_info
->nrxq
, 0, lro
) &&
190 !alloc_uld_rxqs(adap
, rxq_info
, rxq_info
->nciq
,
191 rxq_info
->nrxq
, lro
));
194 static void t4_free_uld_rxqs(struct adapter
*adap
, int n
,
195 struct sge_ofld_rxq
*q
)
197 for ( ; n
; n
--, q
++) {
199 free_rspq_fl(adap
, &q
->rspq
,
200 q
->fl
.size
? &q
->fl
: NULL
);
205 void free_sge_queues_uld(struct adapter
*adap
, unsigned int uld_type
)
207 struct sge_uld_rxq_info
*rxq_info
= adap
->sge
.uld_rxq_info
[uld_type
];
210 t4_free_uld_rxqs(adap
, rxq_info
->nciq
,
211 rxq_info
->uldrxq
+ rxq_info
->nrxq
);
212 t4_free_uld_rxqs(adap
, rxq_info
->nrxq
, rxq_info
->uldrxq
);
213 if (adap
->flags
& USING_MSIX
)
214 kfree(rxq_info
->msix_tbl
);
217 int cfg_queues_uld(struct adapter
*adap
, unsigned int uld_type
,
218 const struct cxgb4_pci_uld_info
*uld_info
)
220 struct sge
*s
= &adap
->sge
;
221 struct sge_uld_rxq_info
*rxq_info
;
224 rxq_info
= kzalloc(sizeof(*rxq_info
), GFP_KERNEL
);
228 if (uld_info
->nrxq
> s
->nqs_per_uld
)
229 rxq_info
->nrxq
= s
->nqs_per_uld
;
231 rxq_info
->nrxq
= uld_info
->nrxq
;
234 else if (uld_info
->nciq
&& uld_info
->nciq
> s
->nqs_per_uld
)
235 rxq_info
->nciq
= s
->nqs_per_uld
;
237 rxq_info
->nciq
= uld_info
->nciq
;
239 nrxq
= rxq_info
->nrxq
+ rxq_info
->nciq
; /* total rxq's */
240 rxq_info
->uldrxq
= kcalloc(nrxq
, sizeof(struct sge_ofld_rxq
),
242 if (!rxq_info
->uldrxq
) {
247 rxq_info
->rspq_id
= kcalloc(nrxq
, sizeof(unsigned short), GFP_KERNEL
);
248 if (!rxq_info
->uldrxq
) {
249 kfree(rxq_info
->uldrxq
);
254 for (i
= 0; i
< rxq_info
->nrxq
; i
++) {
255 struct sge_ofld_rxq
*r
= &rxq_info
->uldrxq
[i
];
257 init_rspq(adap
, &r
->rspq
, 5, 1, uld_info
->rxq_size
, 64);
258 r
->rspq
.uld
= uld_type
;
262 for (i
= rxq_info
->nrxq
; i
< nrxq
; i
++) {
263 struct sge_ofld_rxq
*r
= &rxq_info
->uldrxq
[i
];
265 init_rspq(adap
, &r
->rspq
, 5, 1, uld_info
->ciq_size
, 64);
266 r
->rspq
.uld
= uld_type
;
270 memcpy(rxq_info
->name
, uld_info
->name
, IFNAMSIZ
);
271 adap
->sge
.uld_rxq_info
[uld_type
] = rxq_info
;
276 void free_queues_uld(struct adapter
*adap
, unsigned int uld_type
)
278 struct sge_uld_rxq_info
*rxq_info
= adap
->sge
.uld_rxq_info
[uld_type
];
280 kfree(rxq_info
->rspq_id
);
281 kfree(rxq_info
->uldrxq
);
285 int request_msix_queue_irqs_uld(struct adapter
*adap
, unsigned int uld_type
)
287 struct sge_uld_rxq_info
*rxq_info
= adap
->sge
.uld_rxq_info
[uld_type
];
288 int idx
, bmap_idx
, err
= 0;
290 for_each_uldrxq(rxq_info
, idx
) {
291 bmap_idx
= rxq_info
->msix_tbl
[idx
];
292 err
= request_irq(adap
->msix_info_ulds
[bmap_idx
].vec
,
294 adap
->msix_info_ulds
[bmap_idx
].desc
,
295 &rxq_info
->uldrxq
[idx
].rspq
);
302 bmap_idx
= rxq_info
->msix_tbl
[idx
];
303 free_msix_idx_in_bmap(adap
, bmap_idx
);
304 free_irq(adap
->msix_info_ulds
[bmap_idx
].vec
,
305 &rxq_info
->uldrxq
[idx
].rspq
);
310 void free_msix_queue_irqs_uld(struct adapter
*adap
, unsigned int uld_type
)
312 struct sge_uld_rxq_info
*rxq_info
= adap
->sge
.uld_rxq_info
[uld_type
];
315 for_each_uldrxq(rxq_info
, idx
) {
316 unsigned int bmap_idx
= rxq_info
->msix_tbl
[idx
];
318 free_msix_idx_in_bmap(adap
, bmap_idx
);
319 free_irq(adap
->msix_info_ulds
[bmap_idx
].vec
,
320 &rxq_info
->uldrxq
[idx
].rspq
);
324 void name_msix_vecs_uld(struct adapter
*adap
, unsigned int uld_type
)
326 struct sge_uld_rxq_info
*rxq_info
= adap
->sge
.uld_rxq_info
[uld_type
];
327 int n
= sizeof(adap
->msix_info_ulds
[0].desc
);
330 for_each_uldrxq(rxq_info
, idx
) {
331 unsigned int bmap_idx
= rxq_info
->msix_tbl
[idx
];
333 snprintf(adap
->msix_info_ulds
[bmap_idx
].desc
, n
, "%s-%s%d",
334 adap
->port
[0]->name
, rxq_info
->name
, idx
);
338 static void enable_rx(struct adapter
*adap
, struct sge_rspq
*q
)
344 cxgb_busy_poll_init_lock(q
);
345 napi_enable(&q
->napi
);
347 /* 0-increment GTS to start the timer and enable interrupts */
348 t4_write_reg(adap
, MYPF_REG(SGE_PF_GTS_A
),
349 SEINTARM_V(q
->intr_params
) |
350 INGRESSQID_V(q
->cntxt_id
));
353 static void quiesce_rx(struct adapter
*adap
, struct sge_rspq
*q
)
355 if (q
&& q
->handler
) {
356 napi_disable(&q
->napi
);
358 while (!cxgb_poll_lock_napi(q
))
364 void enable_rx_uld(struct adapter
*adap
, unsigned int uld_type
)
366 struct sge_uld_rxq_info
*rxq_info
= adap
->sge
.uld_rxq_info
[uld_type
];
369 for_each_uldrxq(rxq_info
, idx
)
370 enable_rx(adap
, &rxq_info
->uldrxq
[idx
].rspq
);
373 void quiesce_rx_uld(struct adapter
*adap
, unsigned int uld_type
)
375 struct sge_uld_rxq_info
*rxq_info
= adap
->sge
.uld_rxq_info
[uld_type
];
378 for_each_uldrxq(rxq_info
, idx
)
379 quiesce_rx(adap
, &rxq_info
->uldrxq
[idx
].rspq
);
382 static void uld_queue_init(struct adapter
*adap
, unsigned int uld_type
,
383 struct cxgb4_lld_info
*lli
)
385 struct sge_uld_rxq_info
*rxq_info
= adap
->sge
.uld_rxq_info
[uld_type
];
387 lli
->rxq_ids
= rxq_info
->rspq_id
;
388 lli
->nrxq
= rxq_info
->nrxq
;
389 lli
->ciq_ids
= rxq_info
->rspq_id
+ rxq_info
->nrxq
;
390 lli
->nciq
= rxq_info
->nciq
;
393 int uld_mem_alloc(struct adapter
*adap
)
395 struct sge
*s
= &adap
->sge
;
397 adap
->uld
= kcalloc(adap
->num_uld
, sizeof(*adap
->uld
), GFP_KERNEL
);
401 s
->uld_rxq_info
= kzalloc(adap
->num_uld
*
402 sizeof(struct sge_uld_rxq_info
*),
404 if (!s
->uld_rxq_info
)
413 void uld_mem_free(struct adapter
*adap
)
415 struct sge
*s
= &adap
->sge
;
417 kfree(s
->uld_rxq_info
);
421 static void uld_init(struct adapter
*adap
, struct cxgb4_lld_info
*lld
)
425 lld
->pdev
= adap
->pdev
;
427 lld
->l2t
= adap
->l2t
;
428 lld
->tids
= &adap
->tids
;
429 lld
->ports
= adap
->port
;
430 lld
->vr
= &adap
->vres
;
431 lld
->mtus
= adap
->params
.mtus
;
432 lld
->ntxq
= adap
->sge
.iscsiqsets
;
433 lld
->nchan
= adap
->params
.nports
;
434 lld
->nports
= adap
->params
.nports
;
435 lld
->wr_cred
= adap
->params
.ofldq_wr_cred
;
436 lld
->adapter_type
= adap
->params
.chip
;
437 lld
->cclk_ps
= 1000000000 / adap
->params
.vpd
.cclk
;
438 lld
->udb_density
= 1 << adap
->params
.sge
.eq_qpp
;
439 lld
->ucq_density
= 1 << adap
->params
.sge
.iq_qpp
;
440 lld
->filt_mode
= adap
->params
.tp
.vlan_pri_map
;
441 /* MODQ_REQ_MAP sets queues 0-3 to chan 0-3 */
442 for (i
= 0; i
< NCHAN
; i
++)
444 lld
->gts_reg
= adap
->regs
+ MYPF_REG(SGE_PF_GTS_A
);
445 lld
->db_reg
= adap
->regs
+ MYPF_REG(SGE_PF_KDOORBELL_A
);
446 lld
->fw_vers
= adap
->params
.fw_vers
;
447 lld
->dbfifo_int_thresh
= dbfifo_int_thresh
;
448 lld
->sge_ingpadboundary
= adap
->sge
.fl_align
;
449 lld
->sge_egrstatuspagesize
= adap
->sge
.stat_len
;
450 lld
->sge_pktshift
= adap
->sge
.pktshift
;
451 lld
->enable_fw_ofld_conn
= adap
->flags
& FW_OFLD_CONN
;
452 lld
->max_ordird_qp
= adap
->params
.max_ordird_qp
;
453 lld
->max_ird_adapter
= adap
->params
.max_ird_adapter
;
454 lld
->ulptx_memwrite_dsgl
= adap
->params
.ulptx_memwrite_dsgl
;
455 lld
->nodeid
= dev_to_node(adap
->pdev_dev
);
458 static void uld_attach(struct adapter
*adap
, unsigned int uld
)
461 struct cxgb4_lld_info lli
;
463 uld_init(adap
, &lli
);
464 uld_queue_init(adap
, uld
, &lli
);
466 handle
= adap
->uld
[uld
].add(&lli
);
467 if (IS_ERR(handle
)) {
468 dev_warn(adap
->pdev_dev
,
469 "could not attach to the %s driver, error %ld\n",
470 adap
->uld
[uld
].name
, PTR_ERR(handle
));
474 adap
->uld
[uld
].handle
= handle
;
476 if (adap
->flags
& FULL_INIT_DONE
)
477 adap
->uld
[uld
].state_change(handle
, CXGB4_STATE_UP
);
480 int cxgb4_register_pci_uld(enum cxgb4_pci_uld type
,
481 struct cxgb4_pci_uld_info
*p
)
484 struct adapter
*adap
;
486 if (type
>= CXGB4_PCI_ULD_MAX
)
489 mutex_lock(&uld_mutex
);
490 list_for_each_entry(adap
, &adapter_list
, list_node
) {
491 if (!is_pci_uld(adap
))
493 ret
= cfg_queues_uld(adap
, type
, p
);
496 ret
= setup_sge_queues_uld(adap
, type
, p
->lro
);
499 if (adap
->flags
& USING_MSIX
) {
500 name_msix_vecs_uld(adap
, type
);
501 ret
= request_msix_queue_irqs_uld(adap
, type
);
505 if (adap
->flags
& FULL_INIT_DONE
)
506 enable_rx_uld(adap
, type
);
507 if (adap
->uld
[type
].add
) {
511 adap
->uld
[type
] = *p
;
512 uld_attach(adap
, type
);
514 mutex_unlock(&uld_mutex
);
518 if (adap
->flags
& USING_MSIX
)
519 free_msix_queue_irqs_uld(adap
, type
);
521 free_sge_queues_uld(adap
, type
);
523 free_queues_uld(adap
, type
);
525 mutex_unlock(&uld_mutex
);
528 EXPORT_SYMBOL(cxgb4_register_pci_uld
);
530 int cxgb4_unregister_pci_uld(enum cxgb4_pci_uld type
)
532 struct adapter
*adap
;
534 if (type
>= CXGB4_PCI_ULD_MAX
)
537 mutex_lock(&uld_mutex
);
538 list_for_each_entry(adap
, &adapter_list
, list_node
) {
539 if (!is_pci_uld(adap
))
541 adap
->uld
[type
].handle
= NULL
;
542 adap
->uld
[type
].add
= NULL
;
543 if (adap
->flags
& FULL_INIT_DONE
)
544 quiesce_rx_uld(adap
, type
);
545 if (adap
->flags
& USING_MSIX
)
546 free_msix_queue_irqs_uld(adap
, type
);
547 free_sge_queues_uld(adap
, type
);
548 free_queues_uld(adap
, type
);
550 mutex_unlock(&uld_mutex
);
554 EXPORT_SYMBOL(cxgb4_unregister_pci_uld
);
This page took 0.042847 seconds and 5 git commands to generate.