aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */