diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_fcoe.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_fcoe.c | 40 |
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; |