aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe/ixgbe_fcoe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_fcoe.c')
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c
index 4123dec0dfb7..6493049b663d 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ixgbe/ixgbe_fcoe.c
@@ -31,6 +31,7 @@
31#include "ixgbe_dcb_82599.h" 31#include "ixgbe_dcb_82599.h"
32#endif /* CONFIG_IXGBE_DCB */ 32#endif /* CONFIG_IXGBE_DCB */
33#include <linux/if_ether.h> 33#include <linux/if_ether.h>
34#include <linux/gfp.h>
34#include <scsi/scsi_cmnd.h> 35#include <scsi/scsi_cmnd.h>
35#include <scsi/scsi_device.h> 36#include <scsi/scsi_device.h>
36#include <scsi/fc/fc_fs.h> 37#include <scsi/fc/fc_fs.h>
@@ -202,6 +203,15 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
202 addr = sg_dma_address(sg); 203 addr = sg_dma_address(sg);
203 len = sg_dma_len(sg); 204 len = sg_dma_len(sg);
204 while (len) { 205 while (len) {
206 /* max number of buffers allowed in one DDP context */
207 if (j >= IXGBE_BUFFCNT_MAX) {
208 netif_err(adapter, drv, adapter->netdev,
209 "xid=%x:%d,%d,%d:addr=%llx "
210 "not enough descriptors\n",
211 xid, i, j, dmacount, (u64)addr);
212 goto out_noddp_free;
213 }
214
205 /* get the offset of length of current buffer */ 215 /* get the offset of length of current buffer */
206 thisoff = addr & ((dma_addr_t)bufflen - 1); 216 thisoff = addr & ((dma_addr_t)bufflen - 1);
207 thislen = min((bufflen - thisoff), len); 217 thislen = min((bufflen - thisoff), len);
@@ -227,20 +237,13 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
227 len -= thislen; 237 len -= thislen;
228 addr += thislen; 238 addr += thislen;
229 j++; 239 j++;
230 /* max number of buffers allowed in one DDP context */
231 if (j > IXGBE_BUFFCNT_MAX) {
232 DPRINTK(DRV, ERR, "xid=%x:%d,%d,%d:addr=%llx "
233 "not enough descriptors\n",
234 xid, i, j, dmacount, (u64)addr);
235 goto out_noddp_free;
236 }
237 } 240 }
238 } 241 }
239 /* only the last buffer may have non-full bufflen */ 242 /* only the last buffer may have non-full bufflen */
240 lastsize = thisoff + thislen; 243 lastsize = thisoff + thislen;
241 244
242 fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); 245 fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT);
243 fcbuff |= (j << IXGBE_FCBUFF_BUFFCNT_SHIFT); 246 fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT);
244 fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT); 247 fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT);
245 fcbuff |= (IXGBE_FCBUFF_VALID); 248 fcbuff |= (IXGBE_FCBUFF_VALID);
246 249
@@ -520,6 +523,9 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
520 /* Enable L2 eth type filter for FCoE */ 523 /* Enable L2 eth type filter for FCoE */
521 IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE), 524 IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE),
522 (ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN)); 525 (ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN));
526 /* Enable L2 eth type filter for FIP */
527 IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FIP),
528 (ETH_P_FIP | IXGBE_ETQF_FILTER_EN));
523 if (adapter->ring_feature[RING_F_FCOE].indices) { 529 if (adapter->ring_feature[RING_F_FCOE].indices) {
524 /* Use multiple rx queues for FCoE by redirection table */ 530 /* Use multiple rx queues for FCoE by redirection table */
525 for (i = 0; i < IXGBE_FCRETA_SIZE; i++) { 531 for (i = 0; i < IXGBE_FCRETA_SIZE; i++) {
@@ -530,6 +536,12 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
530 } 536 }
531 IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, IXGBE_FCRECTL_ENA); 537 IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, IXGBE_FCRECTL_ENA);
532 IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0); 538 IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0);
539 fcoe_i = f->mask;
540 fcoe_i &= IXGBE_FCRETA_ENTRY_MASK;
541 fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx;
542 IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP),
543 IXGBE_ETQS_QUEUE_EN |
544 (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
533 } else { 545 } else {
534 /* Use single rx queue for FCoE */ 546 /* Use single rx queue for FCoE */
535 fcoe_i = f->mask; 547 fcoe_i = f->mask;
@@ -539,6 +551,12 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
539 IXGBE_ETQS_QUEUE_EN | 551 IXGBE_ETQS_QUEUE_EN |
540 (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT)); 552 (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
541 } 553 }
554 /* send FIP frames to the first FCoE queue */
555 fcoe_i = f->mask;
556 fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx;
557 IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP),
558 IXGBE_ETQS_QUEUE_EN |
559 (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
542 560
543 IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL, 561 IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL,
544 IXGBE_FCRXCTRL_FCOELLI | 562 IXGBE_FCRXCTRL_FCOELLI |
@@ -614,9 +632,9 @@ int ixgbe_fcoe_enable(struct net_device *netdev)
614 netdev->vlan_features |= NETIF_F_FSO; 632 netdev->vlan_features |= NETIF_F_FSO;
615 netdev->vlan_features |= NETIF_F_FCOE_MTU; 633 netdev->vlan_features |= NETIF_F_FCOE_MTU;
616 netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; 634 netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1;
617 netdev_features_change(netdev);
618 635
619 ixgbe_init_interrupt_scheme(adapter); 636 ixgbe_init_interrupt_scheme(adapter);
637 netdev_features_change(netdev);
620 638
621 if (netif_running(netdev)) 639 if (netif_running(netdev))
622 netdev->netdev_ops->ndo_open(netdev); 640 netdev->netdev_ops->ndo_open(netdev);
@@ -660,11 +678,11 @@ int ixgbe_fcoe_disable(struct net_device *netdev)
660 netdev->vlan_features &= ~NETIF_F_FSO; 678 netdev->vlan_features &= ~NETIF_F_FSO;
661 netdev->vlan_features &= ~NETIF_F_FCOE_MTU; 679 netdev->vlan_features &= ~NETIF_F_FCOE_MTU;
662 netdev->fcoe_ddp_xid = 0; 680 netdev->fcoe_ddp_xid = 0;
663 netdev_features_change(netdev);
664 681
665 ixgbe_cleanup_fcoe(adapter); 682 ixgbe_cleanup_fcoe(adapter);
666
667 ixgbe_init_interrupt_scheme(adapter); 683 ixgbe_init_interrupt_scheme(adapter);
684 netdev_features_change(netdev);
685
668 if (netif_running(netdev)) 686 if (netif_running(netdev))
669 netdev->netdev_ops->ndo_open(netdev); 687 netdev->netdev_ops->ndo_open(netdev);
670 rc = 0; 688 rc = 0;