diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_fcoe.c | 105 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_fcoe.h | 13 |
2 files changed, 82 insertions, 36 deletions
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 05920726e824..f5f39edb86ab 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c | |||
@@ -128,7 +128,11 @@ int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid) | |||
128 | if (ddp->sgl) | 128 | if (ddp->sgl) |
129 | pci_unmap_sg(adapter->pdev, ddp->sgl, ddp->sgc, | 129 | pci_unmap_sg(adapter->pdev, ddp->sgl, ddp->sgc, |
130 | DMA_FROM_DEVICE); | 130 | DMA_FROM_DEVICE); |
131 | pci_pool_free(fcoe->pool, ddp->udl, ddp->udp); | 131 | if (ddp->pool) { |
132 | pci_pool_free(ddp->pool, ddp->udl, ddp->udp); | ||
133 | ddp->pool = NULL; | ||
134 | } | ||
135 | |||
132 | ixgbe_fcoe_clear_ddp(ddp); | 136 | ixgbe_fcoe_clear_ddp(ddp); |
133 | 137 | ||
134 | out_ddp_put: | 138 | out_ddp_put: |
@@ -163,6 +167,7 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid, | |||
163 | unsigned int thislen = 0; | 167 | unsigned int thislen = 0; |
164 | u32 fcbuff, fcdmarw, fcfltrw, fcrxctl; | 168 | u32 fcbuff, fcdmarw, fcfltrw, fcrxctl; |
165 | dma_addr_t addr = 0; | 169 | dma_addr_t addr = 0; |
170 | struct pci_pool *pool; | ||
166 | 171 | ||
167 | if (!netdev || !sgl) | 172 | if (!netdev || !sgl) |
168 | return 0; | 173 | return 0; |
@@ -199,12 +204,14 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid, | |||
199 | return 0; | 204 | return 0; |
200 | } | 205 | } |
201 | 206 | ||
202 | /* alloc the udl from our ddp pool */ | 207 | /* alloc the udl from per cpu ddp pool */ |
203 | ddp->udl = pci_pool_alloc(fcoe->pool, GFP_ATOMIC, &ddp->udp); | 208 | pool = *per_cpu_ptr(fcoe->pool, get_cpu()); |
209 | ddp->udl = pci_pool_alloc(pool, GFP_ATOMIC, &ddp->udp); | ||
204 | if (!ddp->udl) { | 210 | if (!ddp->udl) { |
205 | e_err(drv, "failed allocated ddp context\n"); | 211 | e_err(drv, "failed allocated ddp context\n"); |
206 | goto out_noddp_unmap; | 212 | goto out_noddp_unmap; |
207 | } | 213 | } |
214 | ddp->pool = pool; | ||
208 | ddp->sgl = sgl; | 215 | ddp->sgl = sgl; |
209 | ddp->sgc = sgc; | 216 | ddp->sgc = sgc; |
210 | 217 | ||
@@ -268,6 +275,7 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid, | |||
268 | j++; | 275 | j++; |
269 | lastsize = 1; | 276 | lastsize = 1; |
270 | } | 277 | } |
278 | put_cpu(); | ||
271 | 279 | ||
272 | fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); | 280 | fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); |
273 | fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); | 281 | fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); |
@@ -311,11 +319,12 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid, | |||
311 | return 1; | 319 | return 1; |
312 | 320 | ||
313 | out_noddp_free: | 321 | out_noddp_free: |
314 | pci_pool_free(fcoe->pool, ddp->udl, ddp->udp); | 322 | pci_pool_free(pool, ddp->udl, ddp->udp); |
315 | ixgbe_fcoe_clear_ddp(ddp); | 323 | ixgbe_fcoe_clear_ddp(ddp); |
316 | 324 | ||
317 | out_noddp_unmap: | 325 | out_noddp_unmap: |
318 | pci_unmap_sg(adapter->pdev, sgl, sgc, DMA_FROM_DEVICE); | 326 | pci_unmap_sg(adapter->pdev, sgl, sgc, DMA_FROM_DEVICE); |
327 | put_cpu(); | ||
319 | return 0; | 328 | return 0; |
320 | } | 329 | } |
321 | 330 | ||
@@ -585,6 +594,46 @@ int ixgbe_fso(struct ixgbe_adapter *adapter, | |||
585 | return skb_is_gso(skb); | 594 | return skb_is_gso(skb); |
586 | } | 595 | } |
587 | 596 | ||
597 | static void ixgbe_fcoe_ddp_pools_free(struct ixgbe_fcoe *fcoe) | ||
598 | { | ||
599 | unsigned int cpu; | ||
600 | struct pci_pool **pool; | ||
601 | |||
602 | for_each_possible_cpu(cpu) { | ||
603 | pool = per_cpu_ptr(fcoe->pool, cpu); | ||
604 | if (*pool) | ||
605 | pci_pool_destroy(*pool); | ||
606 | } | ||
607 | free_percpu(fcoe->pool); | ||
608 | fcoe->pool = NULL; | ||
609 | } | ||
610 | |||
611 | static void ixgbe_fcoe_ddp_pools_alloc(struct ixgbe_adapter *adapter) | ||
612 | { | ||
613 | struct ixgbe_fcoe *fcoe = &adapter->fcoe; | ||
614 | unsigned int cpu; | ||
615 | struct pci_pool **pool; | ||
616 | char pool_name[32]; | ||
617 | |||
618 | fcoe->pool = alloc_percpu(struct pci_pool *); | ||
619 | if (!fcoe->pool) | ||
620 | return; | ||
621 | |||
622 | /* allocate pci pool for each cpu */ | ||
623 | for_each_possible_cpu(cpu) { | ||
624 | snprintf(pool_name, 32, "ixgbe_fcoe_ddp_%d", cpu); | ||
625 | pool = per_cpu_ptr(fcoe->pool, cpu); | ||
626 | *pool = pci_pool_create(pool_name, | ||
627 | adapter->pdev, IXGBE_FCPTR_MAX, | ||
628 | IXGBE_FCPTR_ALIGN, PAGE_SIZE); | ||
629 | if (!*pool) { | ||
630 | e_err(drv, "failed to alloc DDP pool on cpu:%d\n", cpu); | ||
631 | ixgbe_fcoe_ddp_pools_free(fcoe); | ||
632 | return; | ||
633 | } | ||
634 | } | ||
635 | } | ||
636 | |||
588 | /** | 637 | /** |
589 | * ixgbe_configure_fcoe - configures registers for fcoe at start | 638 | * ixgbe_configure_fcoe - configures registers for fcoe at start |
590 | * @adapter: ptr to ixgbe adapter | 639 | * @adapter: ptr to ixgbe adapter |
@@ -604,22 +653,20 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) | |||
604 | u32 up2tc; | 653 | u32 up2tc; |
605 | #endif | 654 | #endif |
606 | 655 | ||
607 | /* create the pool for ddp if not created yet */ | ||
608 | if (!fcoe->pool) { | 656 | if (!fcoe->pool) { |
609 | /* allocate ddp pool */ | ||
610 | fcoe->pool = pci_pool_create("ixgbe_fcoe_ddp", | ||
611 | adapter->pdev, IXGBE_FCPTR_MAX, | ||
612 | IXGBE_FCPTR_ALIGN, PAGE_SIZE); | ||
613 | if (!fcoe->pool) | ||
614 | e_err(drv, "failed to allocated FCoE DDP pool\n"); | ||
615 | |||
616 | spin_lock_init(&fcoe->lock); | 657 | spin_lock_init(&fcoe->lock); |
617 | 658 | ||
659 | ixgbe_fcoe_ddp_pools_alloc(adapter); | ||
660 | if (!fcoe->pool) { | ||
661 | e_err(drv, "failed to alloc percpu fcoe DDP pools\n"); | ||
662 | return; | ||
663 | } | ||
664 | |||
618 | /* Extra buffer to be shared by all DDPs for HW work around */ | 665 | /* Extra buffer to be shared by all DDPs for HW work around */ |
619 | fcoe->extra_ddp_buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_ATOMIC); | 666 | fcoe->extra_ddp_buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_ATOMIC); |
620 | if (fcoe->extra_ddp_buffer == NULL) { | 667 | if (fcoe->extra_ddp_buffer == NULL) { |
621 | e_err(drv, "failed to allocated extra DDP buffer\n"); | 668 | e_err(drv, "failed to allocated extra DDP buffer\n"); |
622 | goto out_extra_ddp_buffer_alloc; | 669 | goto out_ddp_pools; |
623 | } | 670 | } |
624 | 671 | ||
625 | fcoe->extra_ddp_buffer_dma = | 672 | fcoe->extra_ddp_buffer_dma = |
@@ -630,7 +677,7 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) | |||
630 | if (dma_mapping_error(&adapter->pdev->dev, | 677 | if (dma_mapping_error(&adapter->pdev->dev, |
631 | fcoe->extra_ddp_buffer_dma)) { | 678 | fcoe->extra_ddp_buffer_dma)) { |
632 | e_err(drv, "failed to map extra DDP buffer\n"); | 679 | e_err(drv, "failed to map extra DDP buffer\n"); |
633 | goto out_extra_ddp_buffer_dma; | 680 | goto out_extra_ddp_buffer; |
634 | } | 681 | } |
635 | } | 682 | } |
636 | 683 | ||
@@ -684,11 +731,10 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) | |||
684 | 731 | ||
685 | return; | 732 | return; |
686 | 733 | ||
687 | out_extra_ddp_buffer_dma: | 734 | out_extra_ddp_buffer: |
688 | kfree(fcoe->extra_ddp_buffer); | 735 | kfree(fcoe->extra_ddp_buffer); |
689 | out_extra_ddp_buffer_alloc: | 736 | out_ddp_pools: |
690 | pci_pool_destroy(fcoe->pool); | 737 | ixgbe_fcoe_ddp_pools_free(fcoe); |
691 | fcoe->pool = NULL; | ||
692 | } | 738 | } |
693 | 739 | ||
694 | /** | 740 | /** |
@@ -704,18 +750,17 @@ void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter) | |||
704 | int i; | 750 | int i; |
705 | struct ixgbe_fcoe *fcoe = &adapter->fcoe; | 751 | struct ixgbe_fcoe *fcoe = &adapter->fcoe; |
706 | 752 | ||
707 | /* release ddp resource */ | 753 | if (!fcoe->pool) |
708 | if (fcoe->pool) { | 754 | return; |
709 | for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++) | 755 | |
710 | ixgbe_fcoe_ddp_put(adapter->netdev, i); | 756 | for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++) |
711 | dma_unmap_single(&adapter->pdev->dev, | 757 | ixgbe_fcoe_ddp_put(adapter->netdev, i); |
712 | fcoe->extra_ddp_buffer_dma, | 758 | dma_unmap_single(&adapter->pdev->dev, |
713 | IXGBE_FCBUFF_MIN, | 759 | fcoe->extra_ddp_buffer_dma, |
714 | DMA_FROM_DEVICE); | 760 | IXGBE_FCBUFF_MIN, |
715 | kfree(fcoe->extra_ddp_buffer); | 761 | DMA_FROM_DEVICE); |
716 | pci_pool_destroy(fcoe->pool); | 762 | kfree(fcoe->extra_ddp_buffer); |
717 | fcoe->pool = NULL; | 763 | ixgbe_fcoe_ddp_pools_free(fcoe); |
718 | } | ||
719 | } | 764 | } |
720 | 765 | ||
721 | /** | 766 | /** |
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h index 5a650a4ace66..d876e7ac2257 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/drivers/net/ixgbe/ixgbe_fcoe.h | |||
@@ -62,20 +62,21 @@ struct ixgbe_fcoe_ddp { | |||
62 | struct scatterlist *sgl; | 62 | struct scatterlist *sgl; |
63 | dma_addr_t udp; | 63 | dma_addr_t udp; |
64 | u64 *udl; | 64 | u64 *udl; |
65 | struct pci_pool *pool; | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | struct ixgbe_fcoe { | 68 | struct ixgbe_fcoe { |
68 | #ifdef CONFIG_IXGBE_DCB | 69 | struct pci_pool **pool; |
69 | u8 tc; | ||
70 | u8 up; | ||
71 | #endif | ||
72 | unsigned long mode; | ||
73 | atomic_t refcnt; | 70 | atomic_t refcnt; |
74 | spinlock_t lock; | 71 | spinlock_t lock; |
75 | struct pci_pool *pool; | ||
76 | struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; | 72 | struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; |
77 | unsigned char *extra_ddp_buffer; | 73 | unsigned char *extra_ddp_buffer; |
78 | dma_addr_t extra_ddp_buffer_dma; | 74 | dma_addr_t extra_ddp_buffer_dma; |
75 | unsigned long mode; | ||
76 | #ifdef CONFIG_IXGBE_DCB | ||
77 | u8 tc; | ||
78 | u8 up; | ||
79 | #endif | ||
79 | }; | 80 | }; |
80 | 81 | ||
81 | #endif /* _IXGBE_FCOE_H */ | 82 | #endif /* _IXGBE_FCOE_H */ |