| Linux kernel & device driver programming |
| [ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] |
1 /* 1
2 * Copyright (c) 2007 Mellanox Technologies. A
3 *
4 * This software is available to you under a c
5 * licenses. You may choose to be licensed un
6 * General Public License (GPL) Version 2, ava
7 * COPYING in the main directory of this sourc
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and bi
11 * without modification, are permitted pro
12 * conditions are met:
13 *
14 * - Redistributions of source code must
15 * copyright notice, this list of condi
16 * disclaimer.
17 *
18 * - Redistributions in binary form must
19 * copyright notice, this list of condi
20 * disclaimer in the documentation and/
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT W
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMIT
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR P
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTH
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER L
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARIS
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR
30 * SOFTWARE.
31 *
32 */
33
34 #include <linux/mlx4/cq.h>
35 #include <linux/mlx4/qp.h>
36 #include <linux/skbuff.h>
37 #include <linux/if_ether.h>
38 #include <linux/if_vlan.h>
39 #include <linux/vmalloc.h>
40
41 #include "mlx4_en.h"
42
43 static void *get_wqe(struct mlx4_en_rx_ring *r
44 {
45 int offset = n << ring->srq.wqe_shift;
46 return ring->buf + offset;
47 }
48
49 static void mlx4_en_srq_event(struct mlx4_srq
50 {
51 return;
52 }
53
54 static int mlx4_en_get_frag_header(struct skb_
55 void **ip_h
56 u64 *hdr_fl
57 {
58 *mac_hdr = page_address(frags->page) +
59 *ip_hdr = *mac_hdr + ETH_HLEN;
60 *tcpudp_hdr = (struct tcphdr *)(*ip_hd
61 *hdr_flags = LRO_IPV4 | LRO_TCP;
62
63 return 0;
64 }
65
66 static int mlx4_en_alloc_frag(struct mlx4_en_p
67 struct mlx4_en_r
68 struct skb_frag_
69 struct mlx4_en_r
70 int i)
71 {
72 struct mlx4_en_dev *mdev = priv->mdev;
73 struct mlx4_en_frag_info *frag_info =
74 struct mlx4_en_rx_alloc *page_alloc =
75 struct page *page;
76 dma_addr_t dma;
77
78 if (page_alloc->offset == frag_info->l
79 /* Allocate new page */
80 page = alloc_pages(GFP_ATOMIC
81 if (!page)
82 return -ENOMEM;
83
84 skb_frags[i].page = page_alloc
85 skb_frags[i].page_offset = pag
86 page_alloc->page = page;
87 page_alloc->offset = frag_info
88 } else {
89 page = page_alloc->page;
90 get_page(page);
91
92 skb_frags[i].page = page;
93 skb_frags[i].page_offset = pag
94 page_alloc->offset += frag_inf
95 }
96 dma = pci_map_single(mdev->pdev, page_
97 skb_frags[i].page
98 PCI_DMA_FROMDEVIC
99 rx_desc->data[i].addr = cpu_to_be64(dm
100 return 0;
101 }
102
103 static int mlx4_en_init_allocator(struct mlx4_
104 struct mlx4_
105 {
106 struct mlx4_en_rx_alloc *page_alloc;
107 int i;
108
109 for (i = 0; i < priv->num_frags; i++)
110 page_alloc = &ring->page_alloc
111 page_alloc->page = alloc_pages
112
113 if (!page_alloc->page)
114 goto out;
115
116 page_alloc->offset = priv->fra
117 en_dbg(DRV, priv, "Initialized
118 i, page_alloc->page);
119 }
120 return 0;
121
122 out:
123 while (i--) {
124 page_alloc = &ring->page_alloc
125 put_page(page_alloc->page);
126 page_alloc->page = NULL;
127 }
128 return -ENOMEM;
129 }
130
131 static void mlx4_en_destroy_allocator(struct m
132 struct m
133 {
134 struct mlx4_en_rx_alloc *page_alloc;
135 int i;
136
137 for (i = 0; i < priv->num_frags; i++)
138 page_alloc = &ring->page_alloc
139 en_dbg(DRV, priv, "Freeing all
140 i, page_count(page_allo
141
142 put_page(page_alloc->page);
143 page_alloc->page = NULL;
144 }
145 }
146
147
148 static void mlx4_en_init_rx_desc(struct mlx4_e
149 struct mlx4_e
150 {
151 struct mlx4_en_rx_desc *rx_desc = ring
152 struct skb_frag_struct *skb_frags = ri
153 (i
154 int possible_frags;
155 int i;
156
157 /* Pre-link descriptor */
158 rx_desc->next.next_wqe_index = cpu_to_
159
160 /* Set size and memtype fields */
161 for (i = 0; i < priv->num_frags; i++)
162 skb_frags[i].size = priv->frag
163 rx_desc->data[i].byte_count =
164 cpu_to_be32(priv->frag
165 rx_desc->data[i].lkey = cpu_to
166 }
167
168 /* If the number of used fragments doe
169 * remaining (unused) fragments must b
170 * and a special memory key */
171 possible_frags = (ring->stride - sizeo
172 for (i = priv->num_frags; i < possible
173 rx_desc->data[i].byte_count =
174 rx_desc->data[i].lkey = cpu_to
175 rx_desc->data[i].addr = 0;
176 }
177 }
178
179
180 static int mlx4_en_prepare_rx_desc(struct mlx4
181 struct mlx4
182 {
183 struct mlx4_en_rx_desc *rx_desc = ring
184 struct skb_frag_struct *skb_frags = ri
185 (i
186 int i;
187
188 for (i = 0; i < priv->num_frags; i++)
189 if (mlx4_en_alloc_frag(priv, r
190 goto err;
191
192 return 0;
193
194 err:
195 while (i--)
196 put_page(skb_frags[i].page);
197 return -ENOMEM;
198 }
199
200 static inline void mlx4_en_update_rx_prod_db(s
201 {
202 *ring->wqres.db.db = cpu_to_be32(ring-
203 }
204
205 static void mlx4_en_free_rx_desc(struct mlx4_e
206 struct mlx4_e
207 int index)
208 {
209 struct mlx4_en_dev *mdev = priv->mdev;
210 struct skb_frag_struct *skb_frags;
211 struct mlx4_en_rx_desc *rx_desc = ring
212 dma_addr_t dma;
213 int nr;
214
215 skb_frags = ring->rx_info + (index <<
216 for (nr = 0; nr < priv->num_frags; nr+
217 en_dbg(DRV, priv, "Freeing fra
218 dma = be64_to_cpu(rx_desc->dat
219
220 en_dbg(DRV, priv, "Unmaping bu
221 pci_unmap_single(mdev->pdev, d
222 PCI_DMA_FROMD
223 put_page(skb_frags[nr].page);
224 }
225 }
226
227 static int mlx4_en_fill_rx_buffers(struct mlx4
228 {
229 struct mlx4_en_rx_ring *ring;
230 int ring_ind;
231 int buf_ind;
232 int new_size;
233
234 for (buf_ind = 0; buf_ind < priv->prof
235 for (ring_ind = 0; ring_ind <
236 ring = &priv->rx_ring[
237
238 if (mlx4_en_prepare_rx
239
240 if (ring->actu
241 en_err
242
243 return
244 } else {
245 new_si
246 en_war
247
248
249 goto r
250 }
251 }
252 ring->actual_size++;
253 ring->prod++;
254 }
255 }
256 return 0;
257
258 reduce_rings:
259 for (ring_ind = 0; ring_ind < priv->rx
260 ring = &priv->rx_ring[ring_ind
261 while (ring->actual_size > new
262 ring->actual_size--;
263 ring->prod--;
264 mlx4_en_free_rx_desc(p
265 }
266 ring->size_mask = ring->actual
267 }
268
269 return 0;
270 }
271
272 static void mlx4_en_free_rx_buf(struct mlx4_en
273 struct mlx4_en
274 {
275 int index;
276
277 en_dbg(DRV, priv, "Freeing Rx buf - co
278 ring->cons, ring->prod);
279
280 /* Unmap and free Rx buffers */
281 BUG_ON((u32) (ring->prod - ring->cons)
282 while (ring->cons != ring->prod) {
283 index = ring->cons & ring->siz
284 en_dbg(DRV, priv, "Processing
285 mlx4_en_free_rx_desc(priv, rin
286 ++ring->cons;
287 }
288 }
289
290 int mlx4_en_create_rx_ring(struct mlx4_en_priv
291 struct mlx4_en_rx_r
292 {
293 struct mlx4_en_dev *mdev = priv->mdev;
294 int err;
295 int tmp;
296
297 /* Sanity check SRQ size before procee
298 if (size >= mdev->dev->caps.max_srq_wq
299 return -EINVAL;
300
301 ring->prod = 0;
302 ring->cons = 0;
303 ring->size = size;
304 ring->size_mask = size - 1;
305 ring->stride = stride;
306 ring->log_stride = ffs(ring->stride) -
307 ring->buf_size = ring->size * ring->st
308
309 tmp = size * roundup_pow_of_two(MLX4_E
310 sizeof
311 ring->rx_info = vmalloc(tmp);
312 if (!ring->rx_info) {
313 en_err(priv, "Failed allocatin
314 return -ENOMEM;
315 }
316 en_dbg(DRV, priv, "Allocated rx_info r
317 ring->rx_info, tmp);
318
319 err = mlx4_alloc_hwq_res(mdev->dev, &r
320 ring->buf_siz
321 if (err)
322 goto err_ring;
323
324 err = mlx4_en_map_buffer(&ring->wqres.
325 if (err) {
326 en_err(priv, "Failed to map RX
327 goto err_hwq;
328 }
329 ring->buf = ring->wqres.buf.direct.buf
330
331 /* Configure lro mngr */
332 memset(&ring->lro, 0, sizeof(struct ne
333 ring->lro.dev = priv->dev;
334 ring->lro.features = LRO_F_NAPI;
335 ring->lro.frag_align_pad = NET_IP_ALIG
336 ring->lro.ip_summed = CHECKSUM_UNNECES
337 ring->lro.ip_summed_aggr = CHECKSUM_UN
338 ring->lro.max_desc = mdev->profile.num
339 ring->lro.max_aggr = MAX_SKB_FRAGS;
340 ring->lro.lro_arr = kzalloc(mdev->prof
341 sizeof(str
342 GFP_KERNEL
343 if (!ring->lro.lro_arr) {
344 en_err(priv, "Failed to alloca
345 goto err_map;
346 }
347 ring->lro.get_frag_header = mlx4_en_ge
348
349 return 0;
350
351 err_map:
352 mlx4_en_unmap_buffer(&ring->wqres.buf)
353 err_hwq:
354 mlx4_free_hwq_res(mdev->dev, &ring->wq
355 err_ring:
356 vfree(ring->rx_info);
357 ring->rx_info = NULL;
358 return err;
359 }
360
361 int mlx4_en_activate_rx_rings(struct mlx4_en_p
362 {
363 struct mlx4_en_dev *mdev = priv->mdev;
364 struct mlx4_wqe_srq_next_seg *next;
365 struct mlx4_en_rx_ring *ring;
366 int i;
367 int ring_ind;
368 int err;
369 int stride = roundup_pow_of_two(sizeof
370 DS_SIZ
371 int max_gs = (stride - sizeof(struct m
372
373 for (ring_ind = 0; ring_ind < priv->rx
374 ring = &priv->rx_ring[ring_ind
375
376 ring->prod = 0;
377 ring->cons = 0;
378 ring->actual_size = 0;
379 ring->cqn = priv->rx_cq[ring_i
380
381 ring->stride = stride;
382 ring->log_stride = ffs(ring->s
383 ring->buf_size = ring->size *
384
385 memset(ring->buf, 0, ring->buf
386 mlx4_en_update_rx_prod_db(ring
387
388 /* Initailize all descriptors
389 for (i = 0; i < ring->size; i+
390 mlx4_en_init_rx_desc(p
391
392 /* Initialize page allocators
393 err = mlx4_en_init_allocator(p
394 if (err) {
395 en_err(priv, "Failed i
396 ring_ind--;
397 goto err_allocator;
398 }
399 }
400 err = mlx4_en_fill_rx_buffers(priv);
401 if (err)
402 goto err_buffers;
403
404 for (ring_ind = 0; ring_ind < priv->rx
405 ring = &priv->rx_ring[ring_ind
406
407 mlx4_en_update_rx_prod_db(ring
408
409 /* Configure SRQ representing
410 ring->srq.max = ring->actua
411 ring->srq.max_gs = max_gs;
412 ring->srq.wqe_shift = ilog2(ri
413
414 for (i = 0; i < ring->srq.max;
415 next = get_wqe(ring, i
416 next->next_wqe_index =
417 cpu_to_be16((i + 1) &
418 }
419
420 err = mlx4_srq_alloc(mdev->dev
421 ring->wqr
422 if (err){
423 en_err(priv, "Failed t
424 ring_ind--;
425 goto err_srq;
426 }
427 ring->srq.event = mlx4_en_srq_
428 }
429
430 return 0;
431
432 err_srq:
433 while (ring_ind >= 0) {
434 ring = &priv->rx_ring[ring_ind
435 mlx4_srq_free(mdev->dev, &ring
436 ring_ind--;
437 }
438
439 err_buffers:
440 for (ring_ind = 0; ring_ind < priv->rx
441 mlx4_en_free_rx_buf(priv, &pri
442
443 ring_ind = priv->rx_ring_num - 1;
444 err_allocator:
445 while (ring_ind >= 0) {
446 mlx4_en_destroy_allocator(priv
447 ring_ind--;
448 }
449 return err;
450 }
451
452 void mlx4_en_destroy_rx_ring(struct mlx4_en_pr
453 struct mlx4_en_rx
454 {
455 struct mlx4_en_dev *mdev = priv->mdev;
456
457 kfree(ring->lro.lro_arr);
458 mlx4_en_unmap_buffer(&ring->wqres.buf)
459 mlx4_free_hwq_res(mdev->dev, &ring->wq
460 vfree(ring->rx_info);
461 ring->rx_info = NULL;
462 }
463
464 void mlx4_en_deactivate_rx_ring(struct mlx4_en
465 struct mlx4_en
466 {
467 struct mlx4_en_dev *mdev = priv->mdev;
468
469 mlx4_srq_free(mdev->dev, &ring->srq);
470 mlx4_en_free_rx_buf(priv, ring);
471 mlx4_en_destroy_allocator(priv, ring);
472 }
473
474
475 /* Unmap a completed descriptor and free unuse
476 static int mlx4_en_complete_rx_desc(struct mlx
477 struct mlx
478 struct skb
479 struct skb
480 struct mlx
481 int length
482 {
483 struct mlx4_en_dev *mdev = priv->mdev;
484 struct mlx4_en_frag_info *frag_info;
485 int nr;
486 dma_addr_t dma;
487
488 /* Collect used fragments while replac
489 for (nr = 0; nr < priv->num_frags; nr+
490 frag_info = &priv->frag_info[n
491 if (length <= frag_info->frag_
492 break;
493
494 /* Save page reference in skb
495 skb_frags_rx[nr].page = skb_fr
496 skb_frags_rx[nr].size = skb_fr
497 skb_frags_rx[nr].page_offset =
498 dma = be64_to_cpu(rx_desc->dat
499
500 /* Allocate a replacement page
501 if (mlx4_en_alloc_frag(priv, r
502 goto fail;
503
504 /* Unmap buffer */
505 pci_unmap_single(mdev->pdev, d
506 PCI_DMA_FROMD
507 }
508 /* Adjust size of last fragment to mat
509 if (nr > 0)
510 skb_frags_rx[nr - 1].size = le
511 priv->frag_info[nr - 1
512 return nr;
513
514 fail:
515 /* Drop all accumulated fragments (whi
516 * the descriptor) of this packet; rem
517 while (nr > 0) {
518 nr--;
519 put_page(skb_frags_rx[nr].page
520 }
521 return 0;
522 }
523
524
525 static struct sk_buff *mlx4_en_rx_skb(struct m
526 struct m
527 struct s
528 struct m
529 unsigned
530 {
531 struct mlx4_en_dev *mdev = priv->mdev;
532 struct sk_buff *skb;
533 void *va;
534 int used_frags;
535 dma_addr_t dma;
536
537 skb = dev_alloc_skb(SMALL_PACKET_SIZE
538 if (!skb) {
539 en_dbg(RX_ERR, priv, "Failed a
540 return NULL;
541 }
542 skb->dev = priv->dev;
543 skb_reserve(skb, NET_IP_ALIGN);
544 skb->len = length;
545 skb->truesize = length + sizeof(struct
546
547 /* Get pointer to first fragment so we
548 * (linear part of the) skb */
549 va = page_address(skb_frags[0].page) +
550
551 if (length <= SMALL_PACKET_SIZE) {
552 /* We are copying all relevant
553 * synch buffers for the copy
554 dma = be64_to_cpu(rx_desc->dat
555 dma_sync_single_range_for_cpu(
556
557 skb_copy_to_linear_data(skb, v
558 dma_sync_single_range_for_devi
559
560 skb->tail += length;
561 } else {
562
563 /* Move relevant fragments to
564 used_frags = mlx4_en_complete_
565
566
567 if (unlikely(!used_frags)) {
568 kfree_skb(skb);
569 return NULL;
570 }
571 skb_shinfo(skb)->nr_frags = us
572
573 /* Copy headers into the skb l
574 memcpy(skb->data, va, HEADER_C
575 skb->tail += HEADER_COPY_SIZE;
576
577 /* Skip headers in first fragm
578 skb_shinfo(skb)->frags[0].page
579
580 /* Adjust size of first fragme
581 skb_shinfo(skb)->frags[0].size
582 skb->data_len = length - HEADE
583 }
584 return skb;
585 }
586
587
588 int mlx4_en_process_rx_cq(struct net_device *d
589 {
590 struct mlx4_en_priv *priv = netdev_pri
591 struct mlx4_cqe *cqe;
592 struct mlx4_en_rx_ring *ring = &priv->
593 struct skb_frag_struct *skb_frags;
594 struct skb_frag_struct lro_frags[MLX4_
595 struct mlx4_en_rx_desc *rx_desc;
596 struct sk_buff *skb;
597 int index;
598 int nr;
599 unsigned int length;
600 int polled = 0;
601 int ip_summed;
602
603 if (!priv->port_up)
604 return 0;
605
606 /* We assume a 1:1 mapping between CQE
607 * descriptor offset can be deduced fr
608 * reading 'cqe->index' */
609 index = cq->mcq.cons_index & ring->siz
610 cqe = &cq->buf[index];
611
612 /* Process all completed CQEs */
613 while (XNOR(cqe->owner_sr_opcode & MLX
614 cq->mcq.cons_index & cq->s
615
616 skb_frags = ring->rx_info + (i
617 rx_desc = ring->buf + (index <
618
619 /*
620 * make sure we read the CQE a
621 */
622 rmb();
623
624 /* Drop packet on bad receive
625 if (unlikely((cqe->owner_sr_op
626
627 en_err(priv, "CQE comp
628 "syndrom:%d
629 ((struct mlx
630 ((struct mlx
631 goto next;
632 }
633 if (unlikely(cqe->badfcs_enc &
634 en_dbg(RX_ERR, priv, "
635 goto next;
636 }
637
638 /*
639 * Packet is OK - process it.
640 */
641 length = be32_to_cpu(cqe->byte
642 ring->bytes += length;
643 ring->packets++;
644
645 if (likely(priv->rx_csum)) {
646 if ((cqe->status & cpu
647 (cqe->checksum ==
648 priv->port_sta
649 /* This packet
650 * - DIX Ether
651 * - TCP/IP (v
652 * - without I
653 * - not an IP
654 if (mlx4_en_ca
655 dev->featu
656
657 nr = m
658
659
660
661 if (!n
662
663
664 if (pr
665
666
667
668
669
670
671
672 } else
673
674
675
676
677
678
679 goto n
680 }
681
682 /* LRO not pos
683 ip_summed = CH
684 INC_PERF_COUNT
685 } else {
686 ip_summed = CH
687 priv->port_sta
688 }
689 } else {
690 ip_summed = CHECKSUM_N
691 priv->port_stats.rx_ch
692 }
693
694 skb = mlx4_en_rx_skb(priv, rx_
695 ring->pag
696 if (!skb) {
697 priv->stats.rx_dropped
698 goto next;
699 }
700
701 skb->ip_summed = ip_summed;
702 skb->protocol = eth_type_trans
703 skb_record_rx_queue(skb, cq->r
704
705 /* Push it up the stack */
706 if (priv->vlgrp && (be32_to_cp
707 MLX4_CQE_V
708 vlan_hwaccel_receive_s
709
710 } else
711 netif_receive_skb(skb)
712
713 next:
714 ++cq->mcq.cons_index;
715 index = (cq->mcq.cons_index) &
716 cqe = &cq->buf[index];
717 if (++polled == budget) {
718 /* We are here because
719 * flush only pending
720 lro_flush_all(&ring->l
721 goto out;
722 }
723 }
724
725 /* If CQ is empty flush all LRO sessio
726 lro_flush_all(&ring->lro);
727
728 out:
729 AVG_PERF_COUNTER(priv->pstats.rx_coal_
730 mlx4_cq_set_ci(&cq->mcq);
731 wmb(); /* ensure HW sees CQ consumer b
732 ring->cons = cq->mcq.cons_index;
733 ring->prod += polled; /* Polled descri
734 mlx4_en_update_rx_prod_db(ring);
735 return polled;
736 }
737
738
739 void mlx4_en_rx_irq(struct mlx4_cq *mcq)
740 {
741 struct mlx4_en_cq *cq = container_of(m
742 struct mlx4_en_priv *priv = netdev_pri
743
744 if (priv->port_up)
745 napi_schedule(&cq->napi);
746 else
747 mlx4_en_arm_cq(priv, cq);
748 }
749
750 /* Rx CQ polling - called by NAPI */
751 int mlx4_en_poll_rx_cq(struct napi_struct *nap
752 {
753 struct mlx4_en_cq *cq = container_of(n
754 struct net_device *dev = cq->dev;
755 struct mlx4_en_priv *priv = netdev_pri
756 int done;
757
758 done = mlx4_en_process_rx_cq(dev, cq,
759
760 /* If we used up all the quota - we're
761 if (done == budget)
762 INC_PERF_COUNTER(priv->pstats.
763 else {
764 /* Done for now */
765 napi_complete(napi);
766 mlx4_en_arm_cq(priv, cq);
767 }
768 return done;
769 }
770
771
772 /* Calculate the last offset position that acc
773 * (assuming fagment size = stride-align) */
774 static int mlx4_en_last_alloc_offset(struct ml
775 {
776 u16 res = MLX4_EN_ALLOC_SIZE % stride;
777 u16 offset = MLX4_EN_ALLOC_SIZE - stri
778
779 en_dbg(DRV, priv, "Calculated last off
780 "res:%d offset:%d\
781 return offset;
782 }
783
784
785 static int frag_sizes[] = {
786 FRAG_SZ0,
787 FRAG_SZ1,
788 FRAG_SZ2,
789 FRAG_SZ3
790 };
791
792 void mlx4_en_calc_rx_buf(struct net_device *de
793 {
794 struct mlx4_en_priv *priv = netdev_pri
795 int eff_mtu = dev->mtu + ETH_HLEN + VL
796 int buf_size = 0;
797 int i = 0;
798
799 while (buf_size < eff_mtu) {
800 priv->frag_info[i].frag_size =
801 (eff_mtu > buf_size +
802 frag_sizes[i]
803 priv->frag_info[i].frag_prefix
804 if (!i) {
805 priv->frag_info[i].fra
806 priv->frag_info[i].fra
807 ALIGN(frag_siz
808 } else {
809 priv->frag_info[i].fra
810 priv->frag_info[i].fra
811 ALIGN(frag_siz
812 }
813 priv->frag_info[i].last_offset
814
815
816 buf_size += priv->frag_info[i]
817 i++;
818 }
819
820 priv->num_frags = i;
821 priv->rx_skb_size = eff_mtu;
822 priv->log_rx_info = ROUNDUP_LOG2(i * s
823
824 en_dbg(DRV, priv, "Rx buffer scatter-l
825 "num_frags:%d):\n", eff_mtu,
826 for (i = 0; i < priv->num_frags; i++)
827 en_dbg(DRV, priv, " frag:%d -
828 "stride:%d las
829 priv->frag_inf
830 priv->frag_inf
831 priv->frag_inf
832 priv->frag_inf
833 priv->frag_inf
834 }
835 }
836
837 /* RSS related functions */
838
839 /* Calculate rss size and map each entry in rs
840 void mlx4_en_set_default_rss_map(struct mlx4_e
841 struct mlx4_e
842 int num_entri
843 {
844 int i;
845
846 rss_map->size = roundup_pow_of_two(num
847 en_dbg(DRV, priv, "Setting default RSS
848 rss_map->size);
849
850 for (i = 0; i < rss_map->size; i++) {
851 rss_map->map[i] = i % num_ring
852 en_dbg(DRV, priv, "Entry %d --
853 }
854 }
855
856 static int mlx4_en_config_rss_qp(struct mlx4_e
857 int qpn, int
858 enum mlx4_qp_
859 struct mlx4_q
860 {
861 struct mlx4_en_dev *mdev = priv->mdev;
862 struct mlx4_qp_context *context;
863 int err = 0;
864
865 context = kmalloc(sizeof *context , GF
866 if (!context) {
867 en_err(priv, "Failed to alloca
868 return -ENOMEM;
869 }
870
871 err = mlx4_qp_alloc(mdev->dev, qpn, qp
872 if (err) {
873 en_err(priv, "Failed to alloca
874 goto out;
875 }
876 qp->event = mlx4_en_sqp_event;
877
878 memset(context, 0, sizeof *context);
879 mlx4_en_fill_qp_context(priv, 0, 0, 0,
880
881 err = mlx4_qp_to_ready(mdev->dev, &pri
882 if (err) {
883 mlx4_qp_remove(mdev->dev, qp);
884 mlx4_qp_free(mdev->dev, qp);
885 }
886 out:
887 kfree(context);
888 return err;
889 }
890
891 /* Allocate rx qp's and configure them accordi
892 int mlx4_en_config_rss_steer(struct mlx4_en_pr
893 {
894 struct mlx4_en_dev *mdev = priv->mdev;
895 struct mlx4_en_rss_map *rss_map = &pri
896 struct mlx4_qp_context context;
897 struct mlx4_en_rss_context *rss_contex
898 void *ptr;
899 int rss_xor = mdev->profile.rss_xor;
900 u8 rss_mask = mdev->profile.rss_mask;
901 int i, srqn, qpn, cqn;
902 int err = 0;
903 int good_qps = 0;
904
905 en_dbg(DRV, priv, "Configuring rss ste
906 err = mlx4_qp_reserve_range(mdev->dev,
907 rss_map->s
908 if (err) {
909 en_err(priv, "Failed reserving
910 return err;
911 }
912
913 for (i = 0; i < rss_map->size; i++) {
914 cqn = priv->rx_ring[rss_map->m
915 srqn = priv->rx_ring[rss_map->
916 qpn = rss_map->base_qpn + i;
917 err = mlx4_en_config_rss_qp(pr
918 &r
919 &r
920 if (err)
921 goto rss_err;
922
923 ++good_qps;
924 }
925
926 /* Configure RSS indirection qp */
927 err = mlx4_qp_reserve_range(mdev->dev,
928 if (err) {
929 en_err(priv, "Failed to reserv
930 "indirection qp\n
931 goto rss_err;
932 }
933 err = mlx4_qp_alloc(mdev->dev, priv->b
934 if (err) {
935 en_err(priv, "Failed to alloca
936 goto reserve_err;
937 }
938 rss_map->indir_qp.event = mlx4_en_sqp_
939 mlx4_en_fill_qp_context(priv, 0, 0, 0,
940 priv->rx_ring[
941
942 ptr = ((void *) &context) + 0x3c;
943 rss_context = (struct mlx4_en_rss_cont
944 rss_context->base_qpn = cpu_to_be32(il
945 (r
946 rss_context->default_qpn = cpu_to_be32
947 rss_context->hash_fn = rss_xor & 0x3;
948 rss_context->flags = rss_mask << 2;
949
950 err = mlx4_qp_to_ready(mdev->dev, &pri
951 &rss_map->indir
952 if (err)
953 goto indir_err;
954
955 return 0;
956
957 indir_err:
958 mlx4_qp_modify(mdev->dev, NULL, rss_ma
959 MLX4_QP_STATE_RST, NULL
960 mlx4_qp_remove(mdev->dev, &rss_map->in
961 mlx4_qp_free(mdev->dev, &rss_map->indi
962 reserve_err:
963 mlx4_qp_release_range(mdev->dev, priv-
964 rss_err:
965 for (i = 0; i < good_qps; i++) {
966 mlx4_qp_modify(mdev->dev, NULL
967 MLX4_QP_STATE_R
968 mlx4_qp_remove(mdev->dev, &rss
969 mlx4_qp_free(mdev->dev, &rss_m
970 }
971 mlx4_qp_release_range(mdev->dev, rss_m
972 return err;
973 }
974
975 void mlx4_en_release_rss_steer(struct mlx4_en_
976 {
977 struct mlx4_en_dev *mdev = priv->mdev;
978 struct mlx4_en_rss_map *rss_map = &pri
979 int i;
980
981 mlx4_qp_modify(mdev->dev, NULL, rss_ma
982 MLX4_QP_STATE_RST, NULL
983 mlx4_qp_remove(mdev->dev, &rss_map->in
984 mlx4_qp_free(mdev->dev, &rss_map->indi
985 mlx4_qp_release_range(mdev->dev, priv-
986
987 for (i = 0; i < rss_map->size; i++) {
988 mlx4_qp_modify(mdev->dev, NULL
989 MLX4_QP_STATE_R
990 mlx4_qp_remove(mdev->dev, &rss
991 mlx4_qp_free(mdev->dev, &rss_m
992 }
993 mlx4_qp_release_range(mdev->dev, rss_m
994 }
995
996
997
998
999
1000
| This page was automatically generated by the LXR engine. |