aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe/fcoe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
-rw-r--r--drivers/scsi/fcoe/fcoe.c51
1 files changed, 25 insertions, 26 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index fd0b2b3b27b8..927b3e63d871 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -1075,7 +1075,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu)
1075 struct sk_buff *skb; 1075 struct sk_buff *skb;
1076#ifdef CONFIG_SMP 1076#ifdef CONFIG_SMP
1077 struct fcoe_percpu_s *p0; 1077 struct fcoe_percpu_s *p0;
1078 unsigned targ_cpu = smp_processor_id(); 1078 unsigned targ_cpu = get_cpu();
1079#endif /* CONFIG_SMP */ 1079#endif /* CONFIG_SMP */
1080 1080
1081 FCOE_DBG("Destroying receive thread for CPU %d\n", cpu); 1081 FCOE_DBG("Destroying receive thread for CPU %d\n", cpu);
@@ -1131,6 +1131,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu)
1131 kfree_skb(skb); 1131 kfree_skb(skb);
1132 spin_unlock_bh(&p->fcoe_rx_list.lock); 1132 spin_unlock_bh(&p->fcoe_rx_list.lock);
1133 } 1133 }
1134 put_cpu();
1134#else 1135#else
1135 /* 1136 /*
1136 * This a non-SMP scenario where the singular Rx thread is 1137 * This a non-SMP scenario where the singular Rx thread is
@@ -1299,8 +1300,8 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
1299 1300
1300 return 0; 1301 return 0;
1301err: 1302err:
1302 fc_lport_get_stats(lport)->ErrorFrames++; 1303 per_cpu_ptr(lport->dev_stats, get_cpu())->ErrorFrames++;
1303 1304 put_cpu();
1304err2: 1305err2:
1305 kfree_skb(skb); 1306 kfree_skb(skb);
1306 return -1; 1307 return -1;
@@ -1529,9 +1530,10 @@ int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
1529 skb_shinfo(skb)->gso_size = 0; 1530 skb_shinfo(skb)->gso_size = 0;
1530 } 1531 }
1531 /* update tx stats: regardless if LLD fails */ 1532 /* update tx stats: regardless if LLD fails */
1532 stats = fc_lport_get_stats(lport); 1533 stats = per_cpu_ptr(lport->dev_stats, get_cpu());
1533 stats->TxFrames++; 1534 stats->TxFrames++;
1534 stats->TxWords += wlen; 1535 stats->TxWords += wlen;
1536 put_cpu();
1535 1537
1536 /* send down to lld */ 1538 /* send down to lld */
1537 fr_dev(fp) = lport; 1539 fr_dev(fp) = lport;
@@ -1595,7 +1597,7 @@ static void fcoe_recv_frame(struct sk_buff *skb)
1595 hp = (struct fcoe_hdr *) skb_network_header(skb); 1597 hp = (struct fcoe_hdr *) skb_network_header(skb);
1596 fh = (struct fc_frame_header *) skb_transport_header(skb); 1598 fh = (struct fc_frame_header *) skb_transport_header(skb);
1597 1599
1598 stats = fc_lport_get_stats(lport); 1600 stats = per_cpu_ptr(lport->dev_stats, get_cpu());
1599 if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) { 1601 if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
1600 if (stats->ErrorFrames < 5) 1602 if (stats->ErrorFrames < 5)
1601 printk(KERN_WARNING "fcoe: FCoE version " 1603 printk(KERN_WARNING "fcoe: FCoE version "
@@ -1604,9 +1606,7 @@ static void fcoe_recv_frame(struct sk_buff *skb)
1604 "initiator supports version " 1606 "initiator supports version "
1605 "%x\n", FC_FCOE_DECAPS_VER(hp), 1607 "%x\n", FC_FCOE_DECAPS_VER(hp),
1606 FC_FCOE_VER); 1608 FC_FCOE_VER);
1607 stats->ErrorFrames++; 1609 goto drop;
1608 kfree_skb(skb);
1609 return;
1610 } 1610 }
1611 1611
1612 skb_pull(skb, sizeof(struct fcoe_hdr)); 1612 skb_pull(skb, sizeof(struct fcoe_hdr));
@@ -1621,16 +1621,12 @@ static void fcoe_recv_frame(struct sk_buff *skb)
1621 fr_sof(fp) = hp->fcoe_sof; 1621 fr_sof(fp) = hp->fcoe_sof;
1622 1622
1623 /* Copy out the CRC and EOF trailer for access */ 1623 /* Copy out the CRC and EOF trailer for access */
1624 if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) { 1624 if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof)))
1625 kfree_skb(skb); 1625 goto drop;
1626 return;
1627 }
1628 fr_eof(fp) = crc_eof.fcoe_eof; 1626 fr_eof(fp) = crc_eof.fcoe_eof;
1629 fr_crc(fp) = crc_eof.fcoe_crc32; 1627 fr_crc(fp) = crc_eof.fcoe_crc32;
1630 if (pskb_trim(skb, fr_len)) { 1628 if (pskb_trim(skb, fr_len))
1631 kfree_skb(skb); 1629 goto drop;
1632 return;
1633 }
1634 1630
1635 /* 1631 /*
1636 * We only check CRC if no offload is available and if it is 1632 * We only check CRC if no offload is available and if it is
@@ -1644,25 +1640,27 @@ static void fcoe_recv_frame(struct sk_buff *skb)
1644 fr_flags(fp) |= FCPHF_CRC_UNCHECKED; 1640 fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
1645 1641
1646 fh = fc_frame_header_get(fp); 1642 fh = fc_frame_header_get(fp);
1647 if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA && 1643 if ((fh->fh_r_ctl != FC_RCTL_DD_SOL_DATA ||
1648 fh->fh_type == FC_TYPE_FCP) { 1644 fh->fh_type != FC_TYPE_FCP) &&
1649 fc_exch_recv(lport, fp); 1645 (fr_flags(fp) & FCPHF_CRC_UNCHECKED)) {
1650 return;
1651 }
1652 if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
1653 if (le32_to_cpu(fr_crc(fp)) != 1646 if (le32_to_cpu(fr_crc(fp)) !=
1654 ~crc32(~0, skb->data, fr_len)) { 1647 ~crc32(~0, skb->data, fr_len)) {
1655 if (stats->InvalidCRCCount < 5) 1648 if (stats->InvalidCRCCount < 5)
1656 printk(KERN_WARNING "fcoe: dropping " 1649 printk(KERN_WARNING "fcoe: dropping "
1657 "frame with CRC error\n"); 1650 "frame with CRC error\n");
1658 stats->InvalidCRCCount++; 1651 stats->InvalidCRCCount++;
1659 stats->ErrorFrames++; 1652 goto drop;
1660 fc_frame_free(fp);
1661 return;
1662 } 1653 }
1663 fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; 1654 fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
1664 } 1655 }
1656 put_cpu();
1665 fc_exch_recv(lport, fp); 1657 fc_exch_recv(lport, fp);
1658 return;
1659
1660drop:
1661 stats->ErrorFrames++;
1662 put_cpu();
1663 kfree_skb(skb);
1666} 1664}
1667 1665
1668/** 1666/**
@@ -1835,8 +1833,9 @@ static int fcoe_device_notification(struct notifier_block *notifier,
1835 if (link_possible && !fcoe_link_ok(lport)) 1833 if (link_possible && !fcoe_link_ok(lport))
1836 fcoe_ctlr_link_up(&fcoe->ctlr); 1834 fcoe_ctlr_link_up(&fcoe->ctlr);
1837 else if (fcoe_ctlr_link_down(&fcoe->ctlr)) { 1835 else if (fcoe_ctlr_link_down(&fcoe->ctlr)) {
1838 stats = fc_lport_get_stats(lport); 1836 stats = per_cpu_ptr(lport->dev_stats, get_cpu());
1839 stats->LinkFailureCount++; 1837 stats->LinkFailureCount++;
1838 put_cpu();
1840 fcoe_clean_pending_queue(lport); 1839 fcoe_clean_pending_queue(lport);
1841 } 1840 }
1842out: 1841out: