aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.c105
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.h13
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
134out_ddp_put: 138out_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
313out_noddp_free: 321out_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
317out_noddp_unmap: 325out_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
597static 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
611static 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
687out_extra_ddp_buffer_dma: 734out_extra_ddp_buffer:
688 kfree(fcoe->extra_ddp_buffer); 735 kfree(fcoe->extra_ddp_buffer);
689out_extra_ddp_buffer_alloc: 736out_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
67struct ixgbe_fcoe { 68struct 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 */