aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBhanu Prakash Gollapudi <bprakash@broadcom.com>2011-01-28 19:05:37 -0500
committerJames Bottomley <James.Bottomley@suse.de>2011-02-12 12:18:18 -0500
commit8597ae8bfe35f5e438b00ba5df852e97ebe1ac23 (patch)
tree64020cecc7ef1bb2923109ed5afea58f59d9bcbe
parent2ca32b4848a865fb088e8c00af0dc194701c373a (diff)
[SCSI] libfcoe: Move common code from fcoe to libfcoe module
To facilitate LLDDs to reuse the code, skb queue related functions are moved to libfcoe, so that both fcoe and bnx2fc drivers can use them. The common structures fcoe_port, fcoe_percpu_s are moved to libfcoe. fcoe_port will now have an opaque pointer that points to corresponding driver's interface structure. Also, fcoe_start_io and fcoe_fc_crc are moved to libfcoe. As part of this change, fixed fcoe_start_io to return ENOMEM if skb_clone fails. Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/fcoe/fcoe.c217
-rw-r--r--drivers/scsi/fcoe/fcoe.h44
-rw-r--r--drivers/scsi/fcoe/fcoe_transport.c200
-rw-r--r--include/scsi/libfcoe.h51
4 files changed, 275 insertions, 237 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 46c57e5755ae..495456fe4520 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -75,7 +75,6 @@ static int fcoe_xmit(struct fc_lport *, struct fc_frame *);
75static int fcoe_rcv(struct sk_buff *, struct net_device *, 75static int fcoe_rcv(struct sk_buff *, struct net_device *,
76 struct packet_type *, struct net_device *); 76 struct packet_type *, struct net_device *);
77static int fcoe_percpu_receive_thread(void *); 77static int fcoe_percpu_receive_thread(void *);
78static void fcoe_clean_pending_queue(struct fc_lport *);
79static void fcoe_percpu_clean(struct fc_lport *); 78static void fcoe_percpu_clean(struct fc_lport *);
80static int fcoe_link_speed_update(struct fc_lport *); 79static int fcoe_link_speed_update(struct fc_lport *);
81static int fcoe_link_ok(struct fc_lport *); 80static int fcoe_link_ok(struct fc_lport *);
@@ -83,7 +82,6 @@ static int fcoe_link_ok(struct fc_lport *);
83static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); 82static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
84static int fcoe_hostlist_add(const struct fc_lport *); 83static int fcoe_hostlist_add(const struct fc_lport *);
85 84
86static void fcoe_check_wait_queue(struct fc_lport *, struct sk_buff *);
87static int fcoe_device_notification(struct notifier_block *, ulong, void *); 85static int fcoe_device_notification(struct notifier_block *, ulong, void *);
88static void fcoe_dev_setup(void); 86static void fcoe_dev_setup(void);
89static void fcoe_dev_cleanup(void); 87static void fcoe_dev_cleanup(void);
@@ -506,7 +504,7 @@ static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
506static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr) 504static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr)
507{ 505{
508 struct fcoe_port *port = lport_priv(lport); 506 struct fcoe_port *port = lport_priv(lport);
509 struct fcoe_interface *fcoe = port->fcoe; 507 struct fcoe_interface *fcoe = port->priv;
510 508
511 rtnl_lock(); 509 rtnl_lock();
512 if (!is_zero_ether_addr(port->data_src_addr)) 510 if (!is_zero_ether_addr(port->data_src_addr))
@@ -562,17 +560,6 @@ static int fcoe_lport_config(struct fc_lport *lport)
562} 560}
563 561
564/** 562/**
565 * fcoe_queue_timer() - The fcoe queue timer
566 * @lport: The local port
567 *
568 * Calls fcoe_check_wait_queue on timeout
569 */
570static void fcoe_queue_timer(ulong lport)
571{
572 fcoe_check_wait_queue((struct fc_lport *)lport, NULL);
573}
574
575/**
576 * fcoe_get_wwn() - Get the world wide name from LLD if it supports it 563 * fcoe_get_wwn() - Get the world wide name from LLD if it supports it
577 * @netdev: the associated net device 564 * @netdev: the associated net device
578 * @wwn: the output WWN 565 * @wwn: the output WWN
@@ -651,7 +638,7 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev)
651 638
652 /* Setup lport private data to point to fcoe softc */ 639 /* Setup lport private data to point to fcoe softc */
653 port = lport_priv(lport); 640 port = lport_priv(lport);
654 fcoe = port->fcoe; 641 fcoe = port->priv;
655 642
656 /* 643 /*
657 * Determine max frame size based on underlying device and optional 644 * Determine max frame size based on underlying device and optional
@@ -761,7 +748,7 @@ bool fcoe_oem_match(struct fc_frame *fp)
761static inline int fcoe_em_config(struct fc_lport *lport) 748static inline int fcoe_em_config(struct fc_lport *lport)
762{ 749{
763 struct fcoe_port *port = lport_priv(lport); 750 struct fcoe_port *port = lport_priv(lport);
764 struct fcoe_interface *fcoe = port->fcoe; 751 struct fcoe_interface *fcoe = port->priv;
765 struct fcoe_interface *oldfcoe = NULL; 752 struct fcoe_interface *oldfcoe = NULL;
766 struct net_device *old_real_dev, *cur_real_dev; 753 struct net_device *old_real_dev, *cur_real_dev;
767 u16 min_xid = FCOE_MIN_XID; 754 u16 min_xid = FCOE_MIN_XID;
@@ -845,7 +832,7 @@ skip_oem:
845static void fcoe_if_destroy(struct fc_lport *lport) 832static void fcoe_if_destroy(struct fc_lport *lport)
846{ 833{
847 struct fcoe_port *port = lport_priv(lport); 834 struct fcoe_port *port = lport_priv(lport);
848 struct fcoe_interface *fcoe = port->fcoe; 835 struct fcoe_interface *fcoe = port->priv;
849 struct net_device *netdev = fcoe->netdev; 836 struct net_device *netdev = fcoe->netdev;
850 837
851 FCOE_NETDEV_DBG(netdev, "Destroying interface\n"); 838 FCOE_NETDEV_DBG(netdev, "Destroying interface\n");
@@ -966,7 +953,9 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
966 } 953 }
967 port = lport_priv(lport); 954 port = lport_priv(lport);
968 port->lport = lport; 955 port->lport = lport;
969 port->fcoe = fcoe; 956 port->priv = fcoe;
957 port->max_queue_depth = FCOE_MAX_QUEUE_DEPTH;
958 port->min_queue_depth = FCOE_MIN_QUEUE_DEPTH;
970 INIT_WORK(&port->destroy_work, fcoe_destroy_work); 959 INIT_WORK(&port->destroy_work, fcoe_destroy_work);
971 960
972 /* configure a fc_lport including the exchange manager */ 961 /* configure a fc_lport including the exchange manager */
@@ -1362,108 +1351,22 @@ err2:
1362} 1351}
1363 1352
1364/** 1353/**
1365 * fcoe_start_io() - Start FCoE I/O 1354 * fcoe_alloc_paged_crc_eof() - Allocate a page to be used for the trailer CRC
1366 * @skb: The packet to be transmitted
1367 *
1368 * This routine is called from the net device to start transmitting
1369 * FCoE packets.
1370 *
1371 * Returns: 0 for success
1372 */
1373static inline int fcoe_start_io(struct sk_buff *skb)
1374{
1375 struct sk_buff *nskb;
1376 int rc;
1377
1378 nskb = skb_clone(skb, GFP_ATOMIC);
1379 rc = dev_queue_xmit(nskb);
1380 if (rc != 0)
1381 return rc;
1382 kfree_skb(skb);
1383 return 0;
1384}
1385
1386/**
1387 * fcoe_get_paged_crc_eof() - Allocate a page to be used for the trailer CRC
1388 * @skb: The packet to be transmitted 1355 * @skb: The packet to be transmitted
1389 * @tlen: The total length of the trailer 1356 * @tlen: The total length of the trailer
1390 * 1357 *
1391 * This routine allocates a page for frame trailers. The page is re-used if
1392 * there is enough room left on it for the current trailer. If there isn't
1393 * enough buffer left a new page is allocated for the trailer. Reference to
1394 * the page from this function as well as the skbs using the page fragments
1395 * ensure that the page is freed at the appropriate time.
1396 *
1397 * Returns: 0 for success 1358 * Returns: 0 for success
1398 */ 1359 */
1399static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen) 1360static int fcoe_alloc_paged_crc_eof(struct sk_buff *skb, int tlen)
1400{ 1361{
1401 struct fcoe_percpu_s *fps; 1362 struct fcoe_percpu_s *fps;
1402 struct page *page; 1363 int rc;
1403 1364
1404 fps = &get_cpu_var(fcoe_percpu); 1365 fps = &get_cpu_var(fcoe_percpu);
1405 page = fps->crc_eof_page; 1366 rc = fcoe_get_paged_crc_eof(skb, tlen, fps);
1406 if (!page) {
1407 page = alloc_page(GFP_ATOMIC);
1408 if (!page) {
1409 put_cpu_var(fcoe_percpu);
1410 return -ENOMEM;
1411 }
1412 fps->crc_eof_page = page;
1413 fps->crc_eof_offset = 0;
1414 }
1415
1416 get_page(page);
1417 skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page,
1418 fps->crc_eof_offset, tlen);
1419 skb->len += tlen;
1420 skb->data_len += tlen;
1421 skb->truesize += tlen;
1422 fps->crc_eof_offset += sizeof(struct fcoe_crc_eof);
1423
1424 if (fps->crc_eof_offset >= PAGE_SIZE) {
1425 fps->crc_eof_page = NULL;
1426 fps->crc_eof_offset = 0;
1427 put_page(page);
1428 }
1429 put_cpu_var(fcoe_percpu); 1367 put_cpu_var(fcoe_percpu);
1430 return 0;
1431}
1432 1368
1433/** 1369 return rc;
1434 * fcoe_fc_crc() - Calculates the CRC for a given frame
1435 * @fp: The frame to be checksumed
1436 *
1437 * This uses crc32() routine to calculate the CRC for a frame
1438 *
1439 * Return: The 32 bit CRC value
1440 */
1441u32 fcoe_fc_crc(struct fc_frame *fp)
1442{
1443 struct sk_buff *skb = fp_skb(fp);
1444 struct skb_frag_struct *frag;
1445 unsigned char *data;
1446 unsigned long off, len, clen;
1447 u32 crc;
1448 unsigned i;
1449
1450 crc = crc32(~0, skb->data, skb_headlen(skb));
1451
1452 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
1453 frag = &skb_shinfo(skb)->frags[i];
1454 off = frag->page_offset;
1455 len = frag->size;
1456 while (len > 0) {
1457 clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK));
1458 data = kmap_atomic(frag->page + (off >> PAGE_SHIFT),
1459 KM_SKB_DATA_SOFTIRQ);
1460 crc = crc32(crc, data + (off & ~PAGE_MASK), clen);
1461 kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ);
1462 off += clen;
1463 len -= clen;
1464 }
1465 }
1466 return crc;
1467} 1370}
1468 1371
1469/** 1372/**
@@ -1486,7 +1389,7 @@ int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
1486 unsigned int tlen; /* trailer length */ 1389 unsigned int tlen; /* trailer length */
1487 unsigned int elen; /* eth header, may include vlan */ 1390 unsigned int elen; /* eth header, may include vlan */
1488 struct fcoe_port *port = lport_priv(lport); 1391 struct fcoe_port *port = lport_priv(lport);
1489 struct fcoe_interface *fcoe = port->fcoe; 1392 struct fcoe_interface *fcoe = port->priv;
1490 u8 sof, eof; 1393 u8 sof, eof;
1491 struct fcoe_hdr *hp; 1394 struct fcoe_hdr *hp;
1492 1395
@@ -1527,7 +1430,7 @@ int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
1527 /* copy port crc and eof to the skb buff */ 1430 /* copy port crc and eof to the skb buff */
1528 if (skb_is_nonlinear(skb)) { 1431 if (skb_is_nonlinear(skb)) {
1529 skb_frag_t *frag; 1432 skb_frag_t *frag;
1530 if (fcoe_get_paged_crc_eof(skb, tlen)) { 1433 if (fcoe_alloc_paged_crc_eof(skb, tlen)) {
1531 kfree_skb(skb); 1434 kfree_skb(skb);
1532 return -ENOMEM; 1435 return -ENOMEM;
1533 } 1436 }
@@ -1636,7 +1539,7 @@ static inline int fcoe_filter_frames(struct fc_lport *lport,
1636 if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA && fh->fh_type == FC_TYPE_FCP) 1539 if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA && fh->fh_type == FC_TYPE_FCP)
1637 return 0; 1540 return 0;
1638 1541
1639 fcoe = ((struct fcoe_port *)lport_priv(lport))->fcoe; 1542 fcoe = ((struct fcoe_port *)lport_priv(lport))->priv;
1640 if (is_fip_mode(&fcoe->ctlr) && fc_frame_payload_op(fp) == ELS_LOGO && 1543 if (is_fip_mode(&fcoe->ctlr) && fc_frame_payload_op(fp) == ELS_LOGO &&
1641 ntoh24(fh->fh_s_id) == FC_FID_FLOGI) { 1544 ntoh24(fh->fh_s_id) == FC_FID_FLOGI) {
1642 FCOE_DBG("fcoe: dropping FCoE lport LOGO in fip mode\n"); 1545 FCOE_DBG("fcoe: dropping FCoE lport LOGO in fip mode\n");
@@ -1771,64 +1674,6 @@ int fcoe_percpu_receive_thread(void *arg)
1771} 1674}
1772 1675
1773/** 1676/**
1774 * fcoe_check_wait_queue() - Attempt to clear the transmit backlog
1775 * @lport: The local port whose backlog is to be cleared
1776 *
1777 * This empties the wait_queue, dequeues the head of the wait_queue queue
1778 * and calls fcoe_start_io() for each packet. If all skb have been
1779 * transmitted it returns the qlen. If an error occurs it restores
1780 * wait_queue (to try again later) and returns -1.
1781 *
1782 * The wait_queue is used when the skb transmit fails. The failed skb
1783 * will go in the wait_queue which will be emptied by the timer function or
1784 * by the next skb transmit.
1785 */
1786static void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb)
1787{
1788 struct fcoe_port *port = lport_priv(lport);
1789 int rc;
1790
1791 spin_lock_bh(&port->fcoe_pending_queue.lock);
1792
1793 if (skb)
1794 __skb_queue_tail(&port->fcoe_pending_queue, skb);
1795
1796 if (port->fcoe_pending_queue_active)
1797 goto out;
1798 port->fcoe_pending_queue_active = 1;
1799
1800 while (port->fcoe_pending_queue.qlen) {
1801 /* keep qlen > 0 until fcoe_start_io succeeds */
1802 port->fcoe_pending_queue.qlen++;
1803 skb = __skb_dequeue(&port->fcoe_pending_queue);
1804
1805 spin_unlock_bh(&port->fcoe_pending_queue.lock);
1806 rc = fcoe_start_io(skb);
1807 spin_lock_bh(&port->fcoe_pending_queue.lock);
1808
1809 if (rc) {
1810 __skb_queue_head(&port->fcoe_pending_queue, skb);
1811 /* undo temporary increment above */
1812 port->fcoe_pending_queue.qlen--;
1813 break;
1814 }
1815 /* undo temporary increment above */
1816 port->fcoe_pending_queue.qlen--;
1817 }
1818
1819 if (port->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH)
1820 lport->qfull = 0;
1821 if (port->fcoe_pending_queue.qlen && !timer_pending(&port->timer))
1822 mod_timer(&port->timer, jiffies + 2);
1823 port->fcoe_pending_queue_active = 0;
1824out:
1825 if (port->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
1826 lport->qfull = 1;
1827 spin_unlock_bh(&port->fcoe_pending_queue.lock);
1828 return;
1829}
1830
1831/**
1832 * fcoe_dev_setup() - Setup the link change notification interface 1677 * fcoe_dev_setup() - Setup the link change notification interface
1833 */ 1678 */
1834static void fcoe_dev_setup(void) 1679static void fcoe_dev_setup(void)
@@ -2180,8 +2025,7 @@ out_nodev:
2180 */ 2025 */
2181int fcoe_link_speed_update(struct fc_lport *lport) 2026int fcoe_link_speed_update(struct fc_lport *lport)
2182{ 2027{
2183 struct fcoe_port *port = lport_priv(lport); 2028 struct net_device *netdev = fcoe_netdev(lport);
2184 struct net_device *netdev = port->fcoe->netdev;
2185 struct ethtool_cmd ecmd = { ETHTOOL_GSET }; 2029 struct ethtool_cmd ecmd = { ETHTOOL_GSET };
2186 2030
2187 if (!dev_ethtool_get_settings(netdev, &ecmd)) { 2031 if (!dev_ethtool_get_settings(netdev, &ecmd)) {
@@ -2212,8 +2056,7 @@ int fcoe_link_speed_update(struct fc_lport *lport)
2212 */ 2056 */
2213int fcoe_link_ok(struct fc_lport *lport) 2057int fcoe_link_ok(struct fc_lport *lport)
2214{ 2058{
2215 struct fcoe_port *port = lport_priv(lport); 2059 struct net_device *netdev = fcoe_netdev(lport);
2216 struct net_device *netdev = port->fcoe->netdev;
2217 2060
2218 if (netif_oper_up(netdev)) 2061 if (netif_oper_up(netdev))
2219 return 0; 2062 return 0;
@@ -2277,24 +2120,6 @@ void fcoe_percpu_clean(struct fc_lport *lport)
2277} 2120}
2278 2121
2279/** 2122/**
2280 * fcoe_clean_pending_queue() - Dequeue a skb and free it
2281 * @lport: The local port to dequeue a skb on
2282 */
2283void fcoe_clean_pending_queue(struct fc_lport *lport)
2284{
2285 struct fcoe_port *port = lport_priv(lport);
2286 struct sk_buff *skb;
2287
2288 spin_lock_bh(&port->fcoe_pending_queue.lock);
2289 while ((skb = __skb_dequeue(&port->fcoe_pending_queue)) != NULL) {
2290 spin_unlock_bh(&port->fcoe_pending_queue.lock);
2291 kfree_skb(skb);
2292 spin_lock_bh(&port->fcoe_pending_queue.lock);
2293 }
2294 spin_unlock_bh(&port->fcoe_pending_queue.lock);
2295}
2296
2297/**
2298 * fcoe_reset() - Reset a local port 2123 * fcoe_reset() - Reset a local port
2299 * @shost: The SCSI host associated with the local port to be reset 2124 * @shost: The SCSI host associated with the local port to be reset
2300 * 2125 *
@@ -2361,7 +2186,7 @@ static int fcoe_hostlist_add(const struct fc_lport *lport)
2361 fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport)); 2186 fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport));
2362 if (!fcoe) { 2187 if (!fcoe) {
2363 port = lport_priv(lport); 2188 port = lport_priv(lport);
2364 fcoe = port->fcoe; 2189 fcoe = port->priv;
2365 list_add_tail(&fcoe->list, &fcoe_hostlist); 2190 list_add_tail(&fcoe->list, &fcoe_hostlist);
2366 } 2191 }
2367 return 0; 2192 return 0;
@@ -2555,7 +2380,7 @@ static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport, u32 did,
2555 void *arg, u32 timeout) 2380 void *arg, u32 timeout)
2556{ 2381{
2557 struct fcoe_port *port = lport_priv(lport); 2382 struct fcoe_port *port = lport_priv(lport);
2558 struct fcoe_interface *fcoe = port->fcoe; 2383 struct fcoe_interface *fcoe = port->priv;
2559 struct fcoe_ctlr *fip = &fcoe->ctlr; 2384 struct fcoe_ctlr *fip = &fcoe->ctlr;
2560 struct fc_frame_header *fh = fc_frame_header_get(fp); 2385 struct fc_frame_header *fh = fc_frame_header_get(fp);
2561 2386
@@ -2588,7 +2413,7 @@ static int fcoe_vport_create(struct fc_vport *vport, bool disabled)
2588 struct Scsi_Host *shost = vport_to_shost(vport); 2413 struct Scsi_Host *shost = vport_to_shost(vport);
2589 struct fc_lport *n_port = shost_priv(shost); 2414 struct fc_lport *n_port = shost_priv(shost);
2590 struct fcoe_port *port = lport_priv(n_port); 2415 struct fcoe_port *port = lport_priv(n_port);
2591 struct fcoe_interface *fcoe = port->fcoe; 2416 struct fcoe_interface *fcoe = port->priv;
2592 struct net_device *netdev = fcoe->netdev; 2417 struct net_device *netdev = fcoe->netdev;
2593 struct fc_lport *vn_port; 2418 struct fc_lport *vn_port;
2594 2419
@@ -2732,7 +2557,7 @@ static void fcoe_set_port_id(struct fc_lport *lport,
2732 u32 port_id, struct fc_frame *fp) 2557 u32 port_id, struct fc_frame *fp)
2733{ 2558{
2734 struct fcoe_port *port = lport_priv(lport); 2559 struct fcoe_port *port = lport_priv(lport);
2735 struct fcoe_interface *fcoe = port->fcoe; 2560 struct fcoe_interface *fcoe = port->priv;
2736 2561
2737 if (fp && fc_frame_payload_op(fp) == ELS_FLOGI) 2562 if (fp && fc_frame_payload_op(fp) == ELS_FLOGI)
2738 fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp); 2563 fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp);
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h
index c69b2c56c2d1..d775128398e9 100644
--- a/drivers/scsi/fcoe/fcoe.h
+++ b/drivers/scsi/fcoe/fcoe.h
@@ -24,7 +24,7 @@
24#include <linux/kthread.h> 24#include <linux/kthread.h>
25 25
26#define FCOE_MAX_QUEUE_DEPTH 256 26#define FCOE_MAX_QUEUE_DEPTH 256
27#define FCOE_LOW_QUEUE_DEPTH 32 27#define FCOE_MIN_QUEUE_DEPTH 32
28 28
29#define FCOE_WORD_TO_BYTE 4 29#define FCOE_WORD_TO_BYTE 4
30 30
@@ -71,21 +71,6 @@ do { \
71 netdev->name, ##args);) 71 netdev->name, ##args);)
72 72
73/** 73/**
74 * struct fcoe_percpu_s - The per-CPU context for FCoE receive threads
75 * @thread: The thread context
76 * @fcoe_rx_list: The queue of pending packets to process
77 * @page: The memory page for calculating frame trailer CRCs
78 * @crc_eof_offset: The offset into the CRC page pointing to available
79 * memory for a new trailer
80 */
81struct fcoe_percpu_s {
82 struct task_struct *thread;
83 struct sk_buff_head fcoe_rx_list;
84 struct page *crc_eof_page;
85 int crc_eof_offset;
86};
87
88/**
89 * struct fcoe_interface - A FCoE interface 74 * struct fcoe_interface - A FCoE interface
90 * @list: Handle for a list of FCoE interfaces 75 * @list: Handle for a list of FCoE interfaces
91 * @netdev: The associated net device 76 * @netdev: The associated net device
@@ -108,30 +93,6 @@ struct fcoe_interface {
108 struct kref kref; 93 struct kref kref;
109}; 94};
110 95
111/**
112 * struct fcoe_port - The FCoE private structure
113 * @fcoe: The associated fcoe interface
114 * @lport: The associated local port
115 * @fcoe_pending_queue: The pending Rx queue of skbs
116 * @fcoe_pending_queue_active: Indicates if the pending queue is active
117 * @timer: The queue timer
118 * @destroy_work: Handle for work context
119 * (to prevent RTNL deadlocks)
120 * @data_srt_addr: Source address for data
121 *
122 * An instance of this structure is to be allocated along with the
123 * Scsi_Host and libfc fc_lport structures.
124 */
125struct fcoe_port {
126 struct fcoe_interface *fcoe;
127 struct fc_lport *lport;
128 struct sk_buff_head fcoe_pending_queue;
129 u8 fcoe_pending_queue_active;
130 struct timer_list timer;
131 struct work_struct destroy_work;
132 u8 data_src_addr[ETH_ALEN];
133};
134
135#define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr) 96#define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr)
136 97
137/** 98/**
@@ -140,7 +101,8 @@ struct fcoe_port {
140 */ 101 */
141static inline struct net_device *fcoe_netdev(const struct fc_lport *lport) 102static inline struct net_device *fcoe_netdev(const struct fc_lport *lport)
142{ 103{
143 return ((struct fcoe_port *)lport_priv(lport))->fcoe->netdev; 104 return ((struct fcoe_interface *)
105 ((struct fcoe_port *)lport_priv(lport))->priv)->netdev;
144} 106}
145 107
146#endif /* _FCOE_H_ */ 108#endif /* _FCOE_H_ */
diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c
index e5aef5639124..745eb9a22d64 100644
--- a/drivers/scsi/fcoe/fcoe_transport.c
+++ b/drivers/scsi/fcoe/fcoe_transport.c
@@ -23,6 +23,7 @@
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/netdevice.h> 24#include <linux/netdevice.h>
25#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/crc32.h>
26#include <scsi/libfcoe.h> 27#include <scsi/libfcoe.h>
27 28
28#include "libfcoe.h" 29#include "libfcoe.h"
@@ -75,6 +76,205 @@ __MODULE_PARM_TYPE(disable, "string");
75MODULE_PARM_DESC(disable, " Disables fcoe on a ethernet interface."); 76MODULE_PARM_DESC(disable, " Disables fcoe on a ethernet interface.");
76 77
77/** 78/**
79 * fcoe_fc_crc() - Calculates the CRC for a given frame
80 * @fp: The frame to be checksumed
81 *
82 * This uses crc32() routine to calculate the CRC for a frame
83 *
84 * Return: The 32 bit CRC value
85 */
86u32 fcoe_fc_crc(struct fc_frame *fp)
87{
88 struct sk_buff *skb = fp_skb(fp);
89 struct skb_frag_struct *frag;
90 unsigned char *data;
91 unsigned long off, len, clen;
92 u32 crc;
93 unsigned i;
94
95 crc = crc32(~0, skb->data, skb_headlen(skb));
96
97 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
98 frag = &skb_shinfo(skb)->frags[i];
99 off = frag->page_offset;
100 len = frag->size;
101 while (len > 0) {
102 clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK));
103 data = kmap_atomic(frag->page + (off >> PAGE_SHIFT),
104 KM_SKB_DATA_SOFTIRQ);
105 crc = crc32(crc, data + (off & ~PAGE_MASK), clen);
106 kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ);
107 off += clen;
108 len -= clen;
109 }
110 }
111 return crc;
112}
113EXPORT_SYMBOL_GPL(fcoe_fc_crc);
114
115/**
116 * fcoe_start_io() - Start FCoE I/O
117 * @skb: The packet to be transmitted
118 *
119 * This routine is called from the net device to start transmitting
120 * FCoE packets.
121 *
122 * Returns: 0 for success
123 */
124int fcoe_start_io(struct sk_buff *skb)
125{
126 struct sk_buff *nskb;
127 int rc;
128
129 nskb = skb_clone(skb, GFP_ATOMIC);
130 if (!nskb)
131 return -ENOMEM;
132 rc = dev_queue_xmit(nskb);
133 if (rc != 0)
134 return rc;
135 kfree_skb(skb);
136 return 0;
137}
138EXPORT_SYMBOL_GPL(fcoe_start_io);
139
140
141/**
142 * fcoe_clean_pending_queue() - Dequeue a skb and free it
143 * @lport: The local port to dequeue a skb on
144 */
145void fcoe_clean_pending_queue(struct fc_lport *lport)
146{
147 struct fcoe_port *port = lport_priv(lport);
148 struct sk_buff *skb;
149
150 spin_lock_bh(&port->fcoe_pending_queue.lock);
151 while ((skb = __skb_dequeue(&port->fcoe_pending_queue)) != NULL) {
152 spin_unlock_bh(&port->fcoe_pending_queue.lock);
153 kfree_skb(skb);
154 spin_lock_bh(&port->fcoe_pending_queue.lock);
155 }
156 spin_unlock_bh(&port->fcoe_pending_queue.lock);
157}
158EXPORT_SYMBOL_GPL(fcoe_clean_pending_queue);
159
160/**
161 * fcoe_check_wait_queue() - Attempt to clear the transmit backlog
162 * @lport: The local port whose backlog is to be cleared
163 *
164 * This empties the wait_queue, dequeues the head of the wait_queue queue
165 * and calls fcoe_start_io() for each packet. If all skb have been
166 * transmitted it returns the qlen. If an error occurs it restores
167 * wait_queue (to try again later) and returns -1.
168 *
169 * The wait_queue is used when the skb transmit fails. The failed skb
170 * will go in the wait_queue which will be emptied by the timer function or
171 * by the next skb transmit.
172 */
173void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb)
174{
175 struct fcoe_port *port = lport_priv(lport);
176 int rc;
177
178 spin_lock_bh(&port->fcoe_pending_queue.lock);
179
180 if (skb)
181 __skb_queue_tail(&port->fcoe_pending_queue, skb);
182
183 if (port->fcoe_pending_queue_active)
184 goto out;
185 port->fcoe_pending_queue_active = 1;
186
187 while (port->fcoe_pending_queue.qlen) {
188 /* keep qlen > 0 until fcoe_start_io succeeds */
189 port->fcoe_pending_queue.qlen++;
190 skb = __skb_dequeue(&port->fcoe_pending_queue);
191
192 spin_unlock_bh(&port->fcoe_pending_queue.lock);
193 rc = fcoe_start_io(skb);
194 spin_lock_bh(&port->fcoe_pending_queue.lock);
195
196 if (rc) {
197 __skb_queue_head(&port->fcoe_pending_queue, skb);
198 /* undo temporary increment above */
199 port->fcoe_pending_queue.qlen--;
200 break;
201 }
202 /* undo temporary increment above */
203 port->fcoe_pending_queue.qlen--;
204 }
205
206 if (port->fcoe_pending_queue.qlen < port->min_queue_depth)
207 lport->qfull = 0;
208 if (port->fcoe_pending_queue.qlen && !timer_pending(&port->timer))
209 mod_timer(&port->timer, jiffies + 2);
210 port->fcoe_pending_queue_active = 0;
211out:
212 if (port->fcoe_pending_queue.qlen > port->max_queue_depth)
213 lport->qfull = 1;
214 spin_unlock_bh(&port->fcoe_pending_queue.lock);
215}
216EXPORT_SYMBOL_GPL(fcoe_check_wait_queue);
217
218/**
219 * fcoe_queue_timer() - The fcoe queue timer
220 * @lport: The local port
221 *
222 * Calls fcoe_check_wait_queue on timeout
223 */
224void fcoe_queue_timer(ulong lport)
225{
226 fcoe_check_wait_queue((struct fc_lport *)lport, NULL);
227}
228EXPORT_SYMBOL_GPL(fcoe_queue_timer);
229
230/**
231 * fcoe_get_paged_crc_eof() - Allocate a page to be used for the trailer CRC
232 * @skb: The packet to be transmitted
233 * @tlen: The total length of the trailer
234 * @fps: The fcoe context
235 *
236 * This routine allocates a page for frame trailers. The page is re-used if
237 * there is enough room left on it for the current trailer. If there isn't
238 * enough buffer left a new page is allocated for the trailer. Reference to
239 * the page from this function as well as the skbs using the page fragments
240 * ensure that the page is freed at the appropriate time.
241 *
242 * Returns: 0 for success
243 */
244int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen,
245 struct fcoe_percpu_s *fps)
246{
247 struct page *page;
248
249 page = fps->crc_eof_page;
250 if (!page) {
251 page = alloc_page(GFP_ATOMIC);
252 if (!page)
253 return -ENOMEM;
254
255 fps->crc_eof_page = page;
256 fps->crc_eof_offset = 0;
257 }
258
259 get_page(page);
260 skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page,
261 fps->crc_eof_offset, tlen);
262 skb->len += tlen;
263 skb->data_len += tlen;
264 skb->truesize += tlen;
265 fps->crc_eof_offset += sizeof(struct fcoe_crc_eof);
266
267 if (fps->crc_eof_offset >= PAGE_SIZE) {
268 fps->crc_eof_page = NULL;
269 fps->crc_eof_offset = 0;
270 put_page(page);
271 }
272
273 return 0;
274}
275EXPORT_SYMBOL_GPL(fcoe_get_paged_crc_eof);
276
277/**
78 * fcoe_transport_lookup - find an fcoe transport that matches a netdev 278 * fcoe_transport_lookup - find an fcoe transport that matches a netdev
79 * @netdev: The netdev to look for from all attached transports 279 * @netdev: The netdev to look for from all attached transports
80 * 280 *
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
index efb6ae5b94ad..e5024634bfab 100644
--- a/include/scsi/libfcoe.h
+++ b/include/scsi/libfcoe.h
@@ -221,6 +221,8 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *,
221u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); 221u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int);
222int fcoe_libfc_config(struct fc_lport *, struct fcoe_ctlr *, 222int fcoe_libfc_config(struct fc_lport *, struct fcoe_ctlr *,
223 const struct libfc_function_template *, int init_fcp); 223 const struct libfc_function_template *, int init_fcp);
224u32 fcoe_fc_crc(struct fc_frame *fp);
225int fcoe_start_io(struct sk_buff *skb);
224 226
225/** 227/**
226 * is_fip_mode() - returns true if FIP mode selected. 228 * is_fip_mode() - returns true if FIP mode selected.
@@ -267,6 +269,55 @@ struct fcoe_transport {
267}; 269};
268 270
269/** 271/**
272 * struct fcoe_percpu_s - The context for FCoE receive thread(s)
273 * @thread: The thread context
274 * @fcoe_rx_list: The queue of pending packets to process
275 * @page: The memory page for calculating frame trailer CRCs
276 * @crc_eof_offset: The offset into the CRC page pointing to available
277 * memory for a new trailer
278 */
279struct fcoe_percpu_s {
280 struct task_struct *thread;
281 struct sk_buff_head fcoe_rx_list;
282 struct page *crc_eof_page;
283 int crc_eof_offset;
284};
285
286/**
287 * struct fcoe_port - The FCoE private structure
288 * @priv: The associated fcoe interface. The structure is
289 * defined by the low level driver
290 * @lport: The associated local port
291 * @fcoe_pending_queue: The pending Rx queue of skbs
292 * @fcoe_pending_queue_active: Indicates if the pending queue is active
293 * @max_queue_depth: Max queue depth of pending queue
294 * @min_queue_depth: Min queue depth of pending queue
295 * @timer: The queue timer
296 * @destroy_work: Handle for work context
297 * (to prevent RTNL deadlocks)
298 * @data_srt_addr: Source address for data
299 *
300 * An instance of this structure is to be allocated along with the
301 * Scsi_Host and libfc fc_lport structures.
302 */
303struct fcoe_port {
304 void *priv;
305 struct fc_lport *lport;
306 struct sk_buff_head fcoe_pending_queue;
307 u8 fcoe_pending_queue_active;
308 u32 max_queue_depth;
309 u32 min_queue_depth;
310 struct timer_list timer;
311 struct work_struct destroy_work;
312 u8 data_src_addr[ETH_ALEN];
313};
314void fcoe_clean_pending_queue(struct fc_lport *);
315void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb);
316void fcoe_queue_timer(ulong lport);
317int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen,
318 struct fcoe_percpu_s *fps);
319
320/**
270 * struct netdev_list 321 * struct netdev_list
271 * A mapping from netdevice to fcoe_transport 322 * A mapping from netdevice to fcoe_transport
272 */ 323 */