diff options
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 217 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe.h | 44 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe_transport.c | 200 | ||||
-rw-r--r-- | include/scsi/libfcoe.h | 51 |
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 *); | |||
75 | static int fcoe_rcv(struct sk_buff *, struct net_device *, | 75 | static int fcoe_rcv(struct sk_buff *, struct net_device *, |
76 | struct packet_type *, struct net_device *); | 76 | struct packet_type *, struct net_device *); |
77 | static int fcoe_percpu_receive_thread(void *); | 77 | static int fcoe_percpu_receive_thread(void *); |
78 | static void fcoe_clean_pending_queue(struct fc_lport *); | ||
79 | static void fcoe_percpu_clean(struct fc_lport *); | 78 | static void fcoe_percpu_clean(struct fc_lport *); |
80 | static int fcoe_link_speed_update(struct fc_lport *); | 79 | static int fcoe_link_speed_update(struct fc_lport *); |
81 | static int fcoe_link_ok(struct fc_lport *); | 80 | static int fcoe_link_ok(struct fc_lport *); |
@@ -83,7 +82,6 @@ static int fcoe_link_ok(struct fc_lport *); | |||
83 | static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); | 82 | static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); |
84 | static int fcoe_hostlist_add(const struct fc_lport *); | 83 | static int fcoe_hostlist_add(const struct fc_lport *); |
85 | 84 | ||
86 | static void fcoe_check_wait_queue(struct fc_lport *, struct sk_buff *); | ||
87 | static int fcoe_device_notification(struct notifier_block *, ulong, void *); | 85 | static int fcoe_device_notification(struct notifier_block *, ulong, void *); |
88 | static void fcoe_dev_setup(void); | 86 | static void fcoe_dev_setup(void); |
89 | static void fcoe_dev_cleanup(void); | 87 | static void fcoe_dev_cleanup(void); |
@@ -506,7 +504,7 @@ static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
506 | static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr) | 504 | static 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 | */ | ||
570 | static 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) | |||
761 | static inline int fcoe_em_config(struct fc_lport *lport) | 748 | static 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: | |||
845 | static void fcoe_if_destroy(struct fc_lport *lport) | 832 | static 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 | */ | ||
1373 | static 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 | */ |
1399 | static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen) | 1360 | static 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 | */ | ||
1441 | u32 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 | */ | ||
1786 | static 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; | ||
1824 | out: | ||
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 | */ |
1834 | static void fcoe_dev_setup(void) | 1679 | static void fcoe_dev_setup(void) |
@@ -2180,8 +2025,7 @@ out_nodev: | |||
2180 | */ | 2025 | */ |
2181 | int fcoe_link_speed_update(struct fc_lport *lport) | 2026 | int 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 | */ |
2213 | int fcoe_link_ok(struct fc_lport *lport) | 2057 | int 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 | */ | ||
2283 | void 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 | */ | ||
81 | struct 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 | */ | ||
125 | struct 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 | */ |
141 | static inline struct net_device *fcoe_netdev(const struct fc_lport *lport) | 102 | static 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"); | |||
75 | MODULE_PARM_DESC(disable, " Disables fcoe on a ethernet interface."); | 76 | MODULE_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 | */ | ||
86 | u32 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 | } | ||
113 | EXPORT_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 | */ | ||
124 | int 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 | } | ||
138 | EXPORT_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 | */ | ||
145 | void 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 | } | ||
158 | EXPORT_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 | */ | ||
173 | void 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; | ||
211 | out: | ||
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 | } | ||
216 | EXPORT_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 | */ | ||
224 | void fcoe_queue_timer(ulong lport) | ||
225 | { | ||
226 | fcoe_check_wait_queue((struct fc_lport *)lport, NULL); | ||
227 | } | ||
228 | EXPORT_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 | */ | ||
244 | int 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 | } | ||
275 | EXPORT_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 *, | |||
221 | u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); | 221 | u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); |
222 | int fcoe_libfc_config(struct fc_lport *, struct fcoe_ctlr *, | 222 | int 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); |
224 | u32 fcoe_fc_crc(struct fc_frame *fp); | ||
225 | int 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 | */ | ||
279 | struct 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 | */ | ||
303 | struct 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 | }; | ||
314 | void fcoe_clean_pending_queue(struct fc_lport *); | ||
315 | void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb); | ||
316 | void fcoe_queue_timer(ulong lport); | ||
317 | int 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 | */ |