| .. | .. |
|---|
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
|---|
| 2 | | -/* Copyright(c) 2013 - 2018 Intel Corporation. */ |
|---|
| 2 | +/* Copyright(c) 2013 - 2019 Intel Corporation. */ |
|---|
| 3 | 3 | |
|---|
| 4 | 4 | #include <linux/types.h> |
|---|
| 5 | 5 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 11 | 11 | |
|---|
| 12 | 12 | #include "fm10k.h" |
|---|
| 13 | 13 | |
|---|
| 14 | | -#define DRV_VERSION "0.23.4-k" |
|---|
| 15 | 14 | #define DRV_SUMMARY "Intel(R) Ethernet Switch Host Interface Driver" |
|---|
| 16 | | -const char fm10k_driver_version[] = DRV_VERSION; |
|---|
| 17 | 15 | char fm10k_driver_name[] = "fm10k"; |
|---|
| 18 | 16 | static const char fm10k_driver_string[] = DRV_SUMMARY; |
|---|
| 19 | 17 | static const char fm10k_copyright[] = |
|---|
| 20 | | - "Copyright(c) 2013 - 2018 Intel Corporation."; |
|---|
| 18 | + "Copyright(c) 2013 - 2019 Intel Corporation."; |
|---|
| 21 | 19 | |
|---|
| 22 | 20 | MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); |
|---|
| 23 | 21 | MODULE_DESCRIPTION(DRV_SUMMARY); |
|---|
| 24 | | -MODULE_LICENSE("GPL"); |
|---|
| 25 | | -MODULE_VERSION(DRV_VERSION); |
|---|
| 22 | +MODULE_LICENSE("GPL v2"); |
|---|
| 26 | 23 | |
|---|
| 27 | 24 | /* single workqueue for entire fm10k driver */ |
|---|
| 28 | 25 | struct workqueue_struct *fm10k_workqueue; |
|---|
| .. | .. |
|---|
| 35 | 32 | **/ |
|---|
| 36 | 33 | static int __init fm10k_init_module(void) |
|---|
| 37 | 34 | { |
|---|
| 38 | | - pr_info("%s - version %s\n", fm10k_driver_string, fm10k_driver_version); |
|---|
| 35 | + int ret; |
|---|
| 36 | + |
|---|
| 37 | + pr_info("%s\n", fm10k_driver_string); |
|---|
| 39 | 38 | pr_info("%s\n", fm10k_copyright); |
|---|
| 40 | 39 | |
|---|
| 41 | 40 | /* create driver workqueue */ |
|---|
| .. | .. |
|---|
| 46 | 45 | |
|---|
| 47 | 46 | fm10k_dbg_init(); |
|---|
| 48 | 47 | |
|---|
| 49 | | - return fm10k_register_pci_driver(); |
|---|
| 48 | + ret = fm10k_register_pci_driver(); |
|---|
| 49 | + if (ret) { |
|---|
| 50 | + fm10k_dbg_exit(); |
|---|
| 51 | + destroy_workqueue(fm10k_workqueue); |
|---|
| 52 | + } |
|---|
| 53 | + |
|---|
| 54 | + return ret; |
|---|
| 50 | 55 | } |
|---|
| 51 | 56 | module_init(fm10k_init_module); |
|---|
| 52 | 57 | |
|---|
| .. | .. |
|---|
| 280 | 285 | /* we need the header to contain the greater of either ETH_HLEN or |
|---|
| 281 | 286 | * 60 bytes if the skb->len is less than 60 for skb_pad. |
|---|
| 282 | 287 | */ |
|---|
| 283 | | - pull_len = eth_get_headlen(va, FM10K_RX_HDR_LEN); |
|---|
| 288 | + pull_len = eth_get_headlen(skb->dev, va, FM10K_RX_HDR_LEN); |
|---|
| 284 | 289 | |
|---|
| 285 | 290 | /* align pull length to size of long to optimize memcpy performance */ |
|---|
| 286 | 291 | memcpy(__skb_put(skb, pull_len), va, ALIGN(pull_len, sizeof(long))); |
|---|
| .. | .. |
|---|
| 313 | 318 | rx_buffer->page_offset; |
|---|
| 314 | 319 | |
|---|
| 315 | 320 | /* prefetch first cache line of first page */ |
|---|
| 316 | | - prefetch(page_addr); |
|---|
| 317 | | -#if L1_CACHE_BYTES < 128 |
|---|
| 318 | | - prefetch(page_addr + L1_CACHE_BYTES); |
|---|
| 319 | | -#endif |
|---|
| 321 | + net_prefetch(page_addr); |
|---|
| 320 | 322 | |
|---|
| 321 | 323 | /* allocate a skb to store the frags */ |
|---|
| 322 | 324 | skb = napi_alloc_skb(&rx_ring->q_vector->napi, |
|---|
| .. | .. |
|---|
| 638 | 640 | static struct ethhdr *fm10k_port_is_vxlan(struct sk_buff *skb) |
|---|
| 639 | 641 | { |
|---|
| 640 | 642 | struct fm10k_intfc *interface = netdev_priv(skb->dev); |
|---|
| 641 | | - struct fm10k_udp_port *vxlan_port; |
|---|
| 642 | 643 | |
|---|
| 643 | | - /* we can only offload a vxlan if we recognize it as such */ |
|---|
| 644 | | - vxlan_port = list_first_entry_or_null(&interface->vxlan_port, |
|---|
| 645 | | - struct fm10k_udp_port, list); |
|---|
| 646 | | - |
|---|
| 647 | | - if (!vxlan_port) |
|---|
| 648 | | - return NULL; |
|---|
| 649 | | - if (vxlan_port->port != udp_hdr(skb)->dest) |
|---|
| 644 | + if (interface->vxlan_port != udp_hdr(skb)->dest) |
|---|
| 650 | 645 | return NULL; |
|---|
| 651 | 646 | |
|---|
| 652 | 647 | /* return offset of udp_hdr plus 8 bytes for VXLAN header */ |
|---|
| .. | .. |
|---|
| 859 | 854 | case IPPROTO_GRE: |
|---|
| 860 | 855 | if (skb->encapsulation) |
|---|
| 861 | 856 | break; |
|---|
| 862 | | - /* fall through */ |
|---|
| 857 | + fallthrough; |
|---|
| 863 | 858 | default: |
|---|
| 864 | 859 | if (unlikely(net_ratelimit())) { |
|---|
| 865 | 860 | dev_warn(tx_ring->dev, |
|---|
| .. | .. |
|---|
| 946 | 941 | struct sk_buff *skb = first->skb; |
|---|
| 947 | 942 | struct fm10k_tx_buffer *tx_buffer; |
|---|
| 948 | 943 | struct fm10k_tx_desc *tx_desc; |
|---|
| 949 | | - struct skb_frag_struct *frag; |
|---|
| 944 | + skb_frag_t *frag; |
|---|
| 950 | 945 | unsigned char *data; |
|---|
| 951 | 946 | dma_addr_t dma; |
|---|
| 952 | 947 | unsigned int data_len, size; |
|---|
| .. | .. |
|---|
| 1037 | 1032 | fm10k_maybe_stop_tx(tx_ring, DESC_NEEDED); |
|---|
| 1038 | 1033 | |
|---|
| 1039 | 1034 | /* notify HW of packet */ |
|---|
| 1040 | | - if (netif_xmit_stopped(txring_txq(tx_ring)) || !skb->xmit_more) { |
|---|
| 1035 | + if (netif_xmit_stopped(txring_txq(tx_ring)) || !netdev_xmit_more()) { |
|---|
| 1041 | 1036 | writel(i, tx_ring->tail); |
|---|
| 1042 | | - |
|---|
| 1043 | | - /* we need this if more than one processor can write to our tail |
|---|
| 1044 | | - * at a time, it synchronizes IO on IA64/Altix systems |
|---|
| 1045 | | - */ |
|---|
| 1046 | | - mmiowb(); |
|---|
| 1047 | 1037 | } |
|---|
| 1048 | 1038 | |
|---|
| 1049 | 1039 | return; |
|---|
| .. | .. |
|---|
| 1078 | 1068 | * + 2 desc gap to keep tail from touching head |
|---|
| 1079 | 1069 | * otherwise try next time |
|---|
| 1080 | 1070 | */ |
|---|
| 1081 | | - for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) |
|---|
| 1082 | | - count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); |
|---|
| 1071 | + for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { |
|---|
| 1072 | + skb_frag_t *frag = &skb_shinfo(skb)->frags[f]; |
|---|
| 1073 | + |
|---|
| 1074 | + count += TXD_USE_COUNT(skb_frag_size(frag)); |
|---|
| 1075 | + } |
|---|
| 1083 | 1076 | |
|---|
| 1084 | 1077 | if (fm10k_maybe_stop_tx(tx_ring, count + 3)) { |
|---|
| 1085 | 1078 | tx_ring->tx_stats.tx_busy++; |
|---|
| .. | .. |
|---|
| 1467 | 1460 | if (!clean_complete) |
|---|
| 1468 | 1461 | return budget; |
|---|
| 1469 | 1462 | |
|---|
| 1470 | | - /* all work done, exit the polling mode */ |
|---|
| 1471 | | - napi_complete_done(napi, work_done); |
|---|
| 1472 | | - |
|---|
| 1473 | | - /* re-enable the q_vector */ |
|---|
| 1474 | | - fm10k_qv_enable(q_vector); |
|---|
| 1463 | + /* Exit the polling mode, but don't re-enable interrupts if stack might |
|---|
| 1464 | + * poll us due to busy-polling |
|---|
| 1465 | + */ |
|---|
| 1466 | + if (likely(napi_complete_done(napi, work_done))) |
|---|
| 1467 | + fm10k_qv_enable(q_vector); |
|---|
| 1475 | 1468 | |
|---|
| 1476 | 1469 | return min(work_done, budget - 1); |
|---|
| 1477 | 1470 | } |
|---|
| .. | .. |
|---|
| 1559 | 1552 | * important, starting with the "most" number of features turned on at once, |
|---|
| 1560 | 1553 | * and ending with the smallest set of features. This way large combinations |
|---|
| 1561 | 1554 | * can be allocated if they're turned on, and smaller combinations are the |
|---|
| 1562 | | - * fallthrough conditions. |
|---|
| 1555 | + * fall through conditions. |
|---|
| 1563 | 1556 | * |
|---|
| 1564 | 1557 | **/ |
|---|
| 1565 | 1558 | static void fm10k_set_num_queues(struct fm10k_intfc *interface) |
|---|
| .. | .. |
|---|
| 1605 | 1598 | { |
|---|
| 1606 | 1599 | struct fm10k_q_vector *q_vector; |
|---|
| 1607 | 1600 | struct fm10k_ring *ring; |
|---|
| 1608 | | - int ring_count, size; |
|---|
| 1601 | + int ring_count; |
|---|
| 1609 | 1602 | |
|---|
| 1610 | 1603 | ring_count = txr_count + rxr_count; |
|---|
| 1611 | | - size = sizeof(struct fm10k_q_vector) + |
|---|
| 1612 | | - (sizeof(struct fm10k_ring) * ring_count); |
|---|
| 1613 | 1604 | |
|---|
| 1614 | 1605 | /* allocate q_vector and rings */ |
|---|
| 1615 | | - q_vector = kzalloc(size, GFP_KERNEL); |
|---|
| 1606 | + q_vector = kzalloc(struct_size(q_vector, ring, ring_count), GFP_KERNEL); |
|---|
| 1616 | 1607 | if (!q_vector) |
|---|
| 1617 | 1608 | return -ENOMEM; |
|---|
| 1618 | 1609 | |
|---|
| .. | .. |
|---|
| 1830 | 1821 | v_budget = min_t(u16, v_budget, num_online_cpus()); |
|---|
| 1831 | 1822 | |
|---|
| 1832 | 1823 | /* account for vectors not related to queues */ |
|---|
| 1833 | | - v_budget += NON_Q_VECTORS(hw); |
|---|
| 1824 | + v_budget += NON_Q_VECTORS; |
|---|
| 1834 | 1825 | |
|---|
| 1835 | 1826 | /* At the same time, hardware can only support a maximum of |
|---|
| 1836 | 1827 | * hw.mac->max_msix_vectors vectors. With features |
|---|
| .. | .. |
|---|
| 1862 | 1853 | } |
|---|
| 1863 | 1854 | |
|---|
| 1864 | 1855 | /* record the number of queues available for q_vectors */ |
|---|
| 1865 | | - interface->num_q_vectors = v_budget - NON_Q_VECTORS(hw); |
|---|
| 1856 | + interface->num_q_vectors = v_budget - NON_Q_VECTORS; |
|---|
| 1866 | 1857 | |
|---|
| 1867 | 1858 | return 0; |
|---|
| 1868 | 1859 | } |
|---|
| .. | .. |
|---|
| 1876 | 1867 | static bool fm10k_cache_ring_qos(struct fm10k_intfc *interface) |
|---|
| 1877 | 1868 | { |
|---|
| 1878 | 1869 | struct net_device *dev = interface->netdev; |
|---|
| 1879 | | - int pc, offset, rss_i, i, q_idx; |
|---|
| 1870 | + int pc, offset, rss_i, i; |
|---|
| 1880 | 1871 | u16 pc_stride = interface->ring_feature[RING_F_QOS].mask + 1; |
|---|
| 1881 | 1872 | u8 num_pcs = netdev_get_num_tc(dev); |
|---|
| 1882 | 1873 | |
|---|
| .. | .. |
|---|
| 1886 | 1877 | rss_i = interface->ring_feature[RING_F_RSS].indices; |
|---|
| 1887 | 1878 | |
|---|
| 1888 | 1879 | for (pc = 0, offset = 0; pc < num_pcs; pc++, offset += rss_i) { |
|---|
| 1889 | | - q_idx = pc; |
|---|
| 1880 | + int q_idx = pc; |
|---|
| 1881 | + |
|---|
| 1890 | 1882 | for (i = 0; i < rss_i; i++) { |
|---|
| 1891 | 1883 | interface->tx_ring[offset + i]->reg_idx = q_idx; |
|---|
| 1892 | 1884 | interface->tx_ring[offset + i]->qos_pc = pc; |
|---|