1b3890e30SAlexander Duyck /* Intel Ethernet Switch Host Interface Driver 2b3890e30SAlexander Duyck * Copyright(c) 2013 - 2014 Intel Corporation. 3b3890e30SAlexander Duyck * 4b3890e30SAlexander Duyck * This program is free software; you can redistribute it and/or modify it 5b3890e30SAlexander Duyck * under the terms and conditions of the GNU General Public License, 6b3890e30SAlexander Duyck * version 2, as published by the Free Software Foundation. 7b3890e30SAlexander Duyck * 8b3890e30SAlexander Duyck * This program is distributed in the hope it will be useful, but WITHOUT 9b3890e30SAlexander Duyck * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10b3890e30SAlexander Duyck * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11b3890e30SAlexander Duyck * more details. 12b3890e30SAlexander Duyck * 13b3890e30SAlexander Duyck * The full GNU General Public License is included in this distribution in 14b3890e30SAlexander Duyck * the file called "COPYING". 15b3890e30SAlexander Duyck * 16b3890e30SAlexander Duyck * Contact Information: 17b3890e30SAlexander Duyck * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 18b3890e30SAlexander Duyck * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 19b3890e30SAlexander Duyck */ 20b3890e30SAlexander Duyck 21b3890e30SAlexander Duyck #include <linux/types.h> 22b3890e30SAlexander Duyck #include <linux/module.h> 23b3890e30SAlexander Duyck #include <net/ipv6.h> 24b3890e30SAlexander Duyck #include <net/ip.h> 25b3890e30SAlexander Duyck #include <net/tcp.h> 26b3890e30SAlexander Duyck #include <linux/if_macvlan.h> 27b3890e30SAlexander Duyck 28b3890e30SAlexander Duyck #include "fm10k.h" 29b3890e30SAlexander Duyck 30b3890e30SAlexander Duyck #define DRV_VERSION "0.12.2-k" 31b3890e30SAlexander Duyck const char fm10k_driver_version[] = DRV_VERSION; 32b3890e30SAlexander Duyck char fm10k_driver_name[] = "fm10k"; 33b3890e30SAlexander Duyck static const char fm10k_driver_string[] = 34b3890e30SAlexander Duyck "Intel(R) Ethernet Switch Host Interface Driver"; 35b3890e30SAlexander Duyck static const char fm10k_copyright[] = 36b3890e30SAlexander Duyck "Copyright (c) 2013 Intel Corporation."; 37b3890e30SAlexander Duyck 38b3890e30SAlexander Duyck MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); 39b3890e30SAlexander Duyck MODULE_DESCRIPTION("Intel(R) Ethernet Switch Host Interface Driver"); 40b3890e30SAlexander Duyck MODULE_LICENSE("GPL"); 41b3890e30SAlexander Duyck MODULE_VERSION(DRV_VERSION); 42b3890e30SAlexander Duyck 436d2ce900SAlexander Duyck /** 446d2ce900SAlexander Duyck * fm10k_init_module - Driver Registration Routine 45b3890e30SAlexander Duyck * 46b3890e30SAlexander Duyck * fm10k_init_module is the first routine called when the driver is 47b3890e30SAlexander Duyck * loaded. All it does is register with the PCI subsystem. 48b3890e30SAlexander Duyck **/ 49b3890e30SAlexander Duyck static int __init fm10k_init_module(void) 50b3890e30SAlexander Duyck { 51b3890e30SAlexander Duyck pr_info("%s - version %s\n", fm10k_driver_string, fm10k_driver_version); 52b3890e30SAlexander Duyck pr_info("%s\n", fm10k_copyright); 53b3890e30SAlexander Duyck 54b3890e30SAlexander Duyck return fm10k_register_pci_driver(); 55b3890e30SAlexander Duyck } 56b3890e30SAlexander Duyck module_init(fm10k_init_module); 57b3890e30SAlexander Duyck 58b3890e30SAlexander Duyck /** 59b3890e30SAlexander Duyck * fm10k_exit_module - Driver Exit Cleanup Routine 60b3890e30SAlexander Duyck * 61b3890e30SAlexander Duyck * fm10k_exit_module is called just before the driver is removed 62b3890e30SAlexander Duyck * from memory. 63b3890e30SAlexander Duyck **/ 64b3890e30SAlexander Duyck static void __exit fm10k_exit_module(void) 65b3890e30SAlexander Duyck { 66b3890e30SAlexander Duyck fm10k_unregister_pci_driver(); 67b3890e30SAlexander Duyck } 68b3890e30SAlexander Duyck module_exit(fm10k_exit_module); 6918283cadSAlexander Duyck 7018283cadSAlexander Duyck /** 7118283cadSAlexander Duyck * fm10k_update_itr - update the dynamic ITR value based on packet size 7218283cadSAlexander Duyck * 7318283cadSAlexander Duyck * Stores a new ITR value based on strictly on packet size. The 7418283cadSAlexander Duyck * divisors and thresholds used by this function were determined based 7518283cadSAlexander Duyck * on theoretical maximum wire speed and testing data, in order to 7618283cadSAlexander Duyck * minimize response time while increasing bulk throughput. 7718283cadSAlexander Duyck * 7818283cadSAlexander Duyck * @ring_container: Container for rings to have ITR updated 7918283cadSAlexander Duyck **/ 8018283cadSAlexander Duyck static void fm10k_update_itr(struct fm10k_ring_container *ring_container) 8118283cadSAlexander Duyck { 8218283cadSAlexander Duyck unsigned int avg_wire_size, packets; 8318283cadSAlexander Duyck 8418283cadSAlexander Duyck /* Only update ITR if we are using adaptive setting */ 8518283cadSAlexander Duyck if (!(ring_container->itr & FM10K_ITR_ADAPTIVE)) 8618283cadSAlexander Duyck goto clear_counts; 8718283cadSAlexander Duyck 8818283cadSAlexander Duyck packets = ring_container->total_packets; 8918283cadSAlexander Duyck if (!packets) 9018283cadSAlexander Duyck goto clear_counts; 9118283cadSAlexander Duyck 9218283cadSAlexander Duyck avg_wire_size = ring_container->total_bytes / packets; 9318283cadSAlexander Duyck 9418283cadSAlexander Duyck /* Add 24 bytes to size to account for CRC, preamble, and gap */ 9518283cadSAlexander Duyck avg_wire_size += 24; 9618283cadSAlexander Duyck 9718283cadSAlexander Duyck /* Don't starve jumbo frames */ 9818283cadSAlexander Duyck if (avg_wire_size > 3000) 9918283cadSAlexander Duyck avg_wire_size = 3000; 10018283cadSAlexander Duyck 10118283cadSAlexander Duyck /* Give a little boost to mid-size frames */ 10218283cadSAlexander Duyck if ((avg_wire_size > 300) && (avg_wire_size < 1200)) 10318283cadSAlexander Duyck avg_wire_size /= 3; 10418283cadSAlexander Duyck else 10518283cadSAlexander Duyck avg_wire_size /= 2; 10618283cadSAlexander Duyck 10718283cadSAlexander Duyck /* write back value and retain adaptive flag */ 10818283cadSAlexander Duyck ring_container->itr = avg_wire_size | FM10K_ITR_ADAPTIVE; 10918283cadSAlexander Duyck 11018283cadSAlexander Duyck clear_counts: 11118283cadSAlexander Duyck ring_container->total_bytes = 0; 11218283cadSAlexander Duyck ring_container->total_packets = 0; 11318283cadSAlexander Duyck } 11418283cadSAlexander Duyck 11518283cadSAlexander Duyck static void fm10k_qv_enable(struct fm10k_q_vector *q_vector) 11618283cadSAlexander Duyck { 11718283cadSAlexander Duyck /* Enable auto-mask and clear the current mask */ 11818283cadSAlexander Duyck u32 itr = FM10K_ITR_ENABLE; 11918283cadSAlexander Duyck 12018283cadSAlexander Duyck /* Update Tx ITR */ 12118283cadSAlexander Duyck fm10k_update_itr(&q_vector->tx); 12218283cadSAlexander Duyck 12318283cadSAlexander Duyck /* Update Rx ITR */ 12418283cadSAlexander Duyck fm10k_update_itr(&q_vector->rx); 12518283cadSAlexander Duyck 12618283cadSAlexander Duyck /* Store Tx itr in timer slot 0 */ 12718283cadSAlexander Duyck itr |= (q_vector->tx.itr & FM10K_ITR_MAX); 12818283cadSAlexander Duyck 12918283cadSAlexander Duyck /* Shift Rx itr to timer slot 1 */ 13018283cadSAlexander Duyck itr |= (q_vector->rx.itr & FM10K_ITR_MAX) << FM10K_ITR_INTERVAL1_SHIFT; 13118283cadSAlexander Duyck 13218283cadSAlexander Duyck /* Write the final value to the ITR register */ 13318283cadSAlexander Duyck writel(itr, q_vector->itr); 13418283cadSAlexander Duyck } 13518283cadSAlexander Duyck 13618283cadSAlexander Duyck static int fm10k_poll(struct napi_struct *napi, int budget) 13718283cadSAlexander Duyck { 13818283cadSAlexander Duyck struct fm10k_q_vector *q_vector = 13918283cadSAlexander Duyck container_of(napi, struct fm10k_q_vector, napi); 14018283cadSAlexander Duyck 14118283cadSAlexander Duyck /* all work done, exit the polling mode */ 14218283cadSAlexander Duyck napi_complete(napi); 14318283cadSAlexander Duyck 14418283cadSAlexander Duyck /* re-enable the q_vector */ 14518283cadSAlexander Duyck fm10k_qv_enable(q_vector); 14618283cadSAlexander Duyck 14718283cadSAlexander Duyck return 0; 14818283cadSAlexander Duyck } 14918283cadSAlexander Duyck 15018283cadSAlexander Duyck /** 15118283cadSAlexander Duyck * fm10k_set_num_queues: Allocate queues for device, feature dependent 15218283cadSAlexander Duyck * @interface: board private structure to initialize 15318283cadSAlexander Duyck * 15418283cadSAlexander Duyck * This is the top level queue allocation routine. The order here is very 15518283cadSAlexander Duyck * important, starting with the "most" number of features turned on at once, 15618283cadSAlexander Duyck * and ending with the smallest set of features. This way large combinations 15718283cadSAlexander Duyck * can be allocated if they're turned on, and smaller combinations are the 15818283cadSAlexander Duyck * fallthrough conditions. 15918283cadSAlexander Duyck * 16018283cadSAlexander Duyck **/ 16118283cadSAlexander Duyck static void fm10k_set_num_queues(struct fm10k_intfc *interface) 16218283cadSAlexander Duyck { 16318283cadSAlexander Duyck /* Start with base case */ 16418283cadSAlexander Duyck interface->num_rx_queues = 1; 16518283cadSAlexander Duyck interface->num_tx_queues = 1; 16618283cadSAlexander Duyck } 16718283cadSAlexander Duyck 16818283cadSAlexander Duyck /** 16918283cadSAlexander Duyck * fm10k_alloc_q_vector - Allocate memory for a single interrupt vector 17018283cadSAlexander Duyck * @interface: board private structure to initialize 17118283cadSAlexander Duyck * @v_count: q_vectors allocated on interface, used for ring interleaving 17218283cadSAlexander Duyck * @v_idx: index of vector in interface struct 17318283cadSAlexander Duyck * @txr_count: total number of Tx rings to allocate 17418283cadSAlexander Duyck * @txr_idx: index of first Tx ring to allocate 17518283cadSAlexander Duyck * @rxr_count: total number of Rx rings to allocate 17618283cadSAlexander Duyck * @rxr_idx: index of first Rx ring to allocate 17718283cadSAlexander Duyck * 17818283cadSAlexander Duyck * We allocate one q_vector. If allocation fails we return -ENOMEM. 17918283cadSAlexander Duyck **/ 18018283cadSAlexander Duyck static int fm10k_alloc_q_vector(struct fm10k_intfc *interface, 18118283cadSAlexander Duyck unsigned int v_count, unsigned int v_idx, 18218283cadSAlexander Duyck unsigned int txr_count, unsigned int txr_idx, 18318283cadSAlexander Duyck unsigned int rxr_count, unsigned int rxr_idx) 18418283cadSAlexander Duyck { 18518283cadSAlexander Duyck struct fm10k_q_vector *q_vector; 18618283cadSAlexander Duyck int ring_count, size; 18718283cadSAlexander Duyck 18818283cadSAlexander Duyck ring_count = txr_count + rxr_count; 18918283cadSAlexander Duyck size = sizeof(struct fm10k_q_vector); 19018283cadSAlexander Duyck 19118283cadSAlexander Duyck /* allocate q_vector and rings */ 19218283cadSAlexander Duyck q_vector = kzalloc(size, GFP_KERNEL); 19318283cadSAlexander Duyck if (!q_vector) 19418283cadSAlexander Duyck return -ENOMEM; 19518283cadSAlexander Duyck 19618283cadSAlexander Duyck /* initialize NAPI */ 19718283cadSAlexander Duyck netif_napi_add(interface->netdev, &q_vector->napi, 19818283cadSAlexander Duyck fm10k_poll, NAPI_POLL_WEIGHT); 19918283cadSAlexander Duyck 20018283cadSAlexander Duyck /* tie q_vector and interface together */ 20118283cadSAlexander Duyck interface->q_vector[v_idx] = q_vector; 20218283cadSAlexander Duyck q_vector->interface = interface; 20318283cadSAlexander Duyck q_vector->v_idx = v_idx; 20418283cadSAlexander Duyck 20518283cadSAlexander Duyck /* save Tx ring container info */ 20618283cadSAlexander Duyck q_vector->tx.itr = interface->tx_itr; 20718283cadSAlexander Duyck q_vector->tx.count = txr_count; 20818283cadSAlexander Duyck 20918283cadSAlexander Duyck /* save Rx ring container info */ 21018283cadSAlexander Duyck q_vector->rx.itr = interface->rx_itr; 21118283cadSAlexander Duyck q_vector->rx.count = rxr_count; 21218283cadSAlexander Duyck 21318283cadSAlexander Duyck return 0; 21418283cadSAlexander Duyck } 21518283cadSAlexander Duyck 21618283cadSAlexander Duyck /** 21718283cadSAlexander Duyck * fm10k_free_q_vector - Free memory allocated for specific interrupt vector 21818283cadSAlexander Duyck * @interface: board private structure to initialize 21918283cadSAlexander Duyck * @v_idx: Index of vector to be freed 22018283cadSAlexander Duyck * 22118283cadSAlexander Duyck * This function frees the memory allocated to the q_vector. In addition if 22218283cadSAlexander Duyck * NAPI is enabled it will delete any references to the NAPI struct prior 22318283cadSAlexander Duyck * to freeing the q_vector. 22418283cadSAlexander Duyck **/ 22518283cadSAlexander Duyck static void fm10k_free_q_vector(struct fm10k_intfc *interface, int v_idx) 22618283cadSAlexander Duyck { 22718283cadSAlexander Duyck struct fm10k_q_vector *q_vector = interface->q_vector[v_idx]; 22818283cadSAlexander Duyck 22918283cadSAlexander Duyck interface->q_vector[v_idx] = NULL; 23018283cadSAlexander Duyck netif_napi_del(&q_vector->napi); 23118283cadSAlexander Duyck kfree_rcu(q_vector, rcu); 23218283cadSAlexander Duyck } 23318283cadSAlexander Duyck 23418283cadSAlexander Duyck /** 23518283cadSAlexander Duyck * fm10k_alloc_q_vectors - Allocate memory for interrupt vectors 23618283cadSAlexander Duyck * @interface: board private structure to initialize 23718283cadSAlexander Duyck * 23818283cadSAlexander Duyck * We allocate one q_vector per queue interrupt. If allocation fails we 23918283cadSAlexander Duyck * return -ENOMEM. 24018283cadSAlexander Duyck **/ 24118283cadSAlexander Duyck static int fm10k_alloc_q_vectors(struct fm10k_intfc *interface) 24218283cadSAlexander Duyck { 24318283cadSAlexander Duyck unsigned int q_vectors = interface->num_q_vectors; 24418283cadSAlexander Duyck unsigned int rxr_remaining = interface->num_rx_queues; 24518283cadSAlexander Duyck unsigned int txr_remaining = interface->num_tx_queues; 24618283cadSAlexander Duyck unsigned int rxr_idx = 0, txr_idx = 0, v_idx = 0; 24718283cadSAlexander Duyck int err; 24818283cadSAlexander Duyck 24918283cadSAlexander Duyck if (q_vectors >= (rxr_remaining + txr_remaining)) { 25018283cadSAlexander Duyck for (; rxr_remaining; v_idx++) { 25118283cadSAlexander Duyck err = fm10k_alloc_q_vector(interface, q_vectors, v_idx, 25218283cadSAlexander Duyck 0, 0, 1, rxr_idx); 25318283cadSAlexander Duyck if (err) 25418283cadSAlexander Duyck goto err_out; 25518283cadSAlexander Duyck 25618283cadSAlexander Duyck /* update counts and index */ 25718283cadSAlexander Duyck rxr_remaining--; 25818283cadSAlexander Duyck rxr_idx++; 25918283cadSAlexander Duyck } 26018283cadSAlexander Duyck } 26118283cadSAlexander Duyck 26218283cadSAlexander Duyck for (; v_idx < q_vectors; v_idx++) { 26318283cadSAlexander Duyck int rqpv = DIV_ROUND_UP(rxr_remaining, q_vectors - v_idx); 26418283cadSAlexander Duyck int tqpv = DIV_ROUND_UP(txr_remaining, q_vectors - v_idx); 26518283cadSAlexander Duyck 26618283cadSAlexander Duyck err = fm10k_alloc_q_vector(interface, q_vectors, v_idx, 26718283cadSAlexander Duyck tqpv, txr_idx, 26818283cadSAlexander Duyck rqpv, rxr_idx); 26918283cadSAlexander Duyck 27018283cadSAlexander Duyck if (err) 27118283cadSAlexander Duyck goto err_out; 27218283cadSAlexander Duyck 27318283cadSAlexander Duyck /* update counts and index */ 27418283cadSAlexander Duyck rxr_remaining -= rqpv; 27518283cadSAlexander Duyck txr_remaining -= tqpv; 27618283cadSAlexander Duyck rxr_idx++; 27718283cadSAlexander Duyck txr_idx++; 27818283cadSAlexander Duyck } 27918283cadSAlexander Duyck 28018283cadSAlexander Duyck return 0; 28118283cadSAlexander Duyck 28218283cadSAlexander Duyck err_out: 28318283cadSAlexander Duyck interface->num_tx_queues = 0; 28418283cadSAlexander Duyck interface->num_rx_queues = 0; 28518283cadSAlexander Duyck interface->num_q_vectors = 0; 28618283cadSAlexander Duyck 28718283cadSAlexander Duyck while (v_idx--) 28818283cadSAlexander Duyck fm10k_free_q_vector(interface, v_idx); 28918283cadSAlexander Duyck 29018283cadSAlexander Duyck return -ENOMEM; 29118283cadSAlexander Duyck } 29218283cadSAlexander Duyck 29318283cadSAlexander Duyck /** 29418283cadSAlexander Duyck * fm10k_free_q_vectors - Free memory allocated for interrupt vectors 29518283cadSAlexander Duyck * @interface: board private structure to initialize 29618283cadSAlexander Duyck * 29718283cadSAlexander Duyck * This function frees the memory allocated to the q_vectors. In addition if 29818283cadSAlexander Duyck * NAPI is enabled it will delete any references to the NAPI struct prior 29918283cadSAlexander Duyck * to freeing the q_vector. 30018283cadSAlexander Duyck **/ 30118283cadSAlexander Duyck static void fm10k_free_q_vectors(struct fm10k_intfc *interface) 30218283cadSAlexander Duyck { 30318283cadSAlexander Duyck int v_idx = interface->num_q_vectors; 30418283cadSAlexander Duyck 30518283cadSAlexander Duyck interface->num_tx_queues = 0; 30618283cadSAlexander Duyck interface->num_rx_queues = 0; 30718283cadSAlexander Duyck interface->num_q_vectors = 0; 30818283cadSAlexander Duyck 30918283cadSAlexander Duyck while (v_idx--) 31018283cadSAlexander Duyck fm10k_free_q_vector(interface, v_idx); 31118283cadSAlexander Duyck } 31218283cadSAlexander Duyck 31318283cadSAlexander Duyck /** 31418283cadSAlexander Duyck * f10k_reset_msix_capability - reset MSI-X capability 31518283cadSAlexander Duyck * @interface: board private structure to initialize 31618283cadSAlexander Duyck * 31718283cadSAlexander Duyck * Reset the MSI-X capability back to its starting state 31818283cadSAlexander Duyck **/ 31918283cadSAlexander Duyck static void fm10k_reset_msix_capability(struct fm10k_intfc *interface) 32018283cadSAlexander Duyck { 32118283cadSAlexander Duyck pci_disable_msix(interface->pdev); 32218283cadSAlexander Duyck kfree(interface->msix_entries); 32318283cadSAlexander Duyck interface->msix_entries = NULL; 32418283cadSAlexander Duyck } 32518283cadSAlexander Duyck 32618283cadSAlexander Duyck /** 32718283cadSAlexander Duyck * f10k_init_msix_capability - configure MSI-X capability 32818283cadSAlexander Duyck * @interface: board private structure to initialize 32918283cadSAlexander Duyck * 33018283cadSAlexander Duyck * Attempt to configure the interrupts using the best available 33118283cadSAlexander Duyck * capabilities of the hardware and the kernel. 33218283cadSAlexander Duyck **/ 33318283cadSAlexander Duyck static int fm10k_init_msix_capability(struct fm10k_intfc *interface) 33418283cadSAlexander Duyck { 33518283cadSAlexander Duyck struct fm10k_hw *hw = &interface->hw; 33618283cadSAlexander Duyck int v_budget, vector; 33718283cadSAlexander Duyck 33818283cadSAlexander Duyck /* It's easy to be greedy for MSI-X vectors, but it really 33918283cadSAlexander Duyck * doesn't do us much good if we have a lot more vectors 34018283cadSAlexander Duyck * than CPU's. So let's be conservative and only ask for 34118283cadSAlexander Duyck * (roughly) the same number of vectors as there are CPU's. 34218283cadSAlexander Duyck * the default is to use pairs of vectors 34318283cadSAlexander Duyck */ 34418283cadSAlexander Duyck v_budget = max(interface->num_rx_queues, interface->num_tx_queues); 34518283cadSAlexander Duyck v_budget = min_t(u16, v_budget, num_online_cpus()); 34618283cadSAlexander Duyck 34718283cadSAlexander Duyck /* account for vectors not related to queues */ 34818283cadSAlexander Duyck v_budget += NON_Q_VECTORS(hw); 34918283cadSAlexander Duyck 35018283cadSAlexander Duyck /* At the same time, hardware can only support a maximum of 35118283cadSAlexander Duyck * hw.mac->max_msix_vectors vectors. With features 35218283cadSAlexander Duyck * such as RSS and VMDq, we can easily surpass the number of Rx and Tx 35318283cadSAlexander Duyck * descriptor queues supported by our device. Thus, we cap it off in 35418283cadSAlexander Duyck * those rare cases where the cpu count also exceeds our vector limit. 35518283cadSAlexander Duyck */ 35618283cadSAlexander Duyck v_budget = min_t(int, v_budget, hw->mac.max_msix_vectors); 35718283cadSAlexander Duyck 35818283cadSAlexander Duyck /* A failure in MSI-X entry allocation is fatal. */ 35918283cadSAlexander Duyck interface->msix_entries = kcalloc(v_budget, sizeof(struct msix_entry), 36018283cadSAlexander Duyck GFP_KERNEL); 36118283cadSAlexander Duyck if (!interface->msix_entries) 36218283cadSAlexander Duyck return -ENOMEM; 36318283cadSAlexander Duyck 36418283cadSAlexander Duyck /* populate entry values */ 36518283cadSAlexander Duyck for (vector = 0; vector < v_budget; vector++) 36618283cadSAlexander Duyck interface->msix_entries[vector].entry = vector; 36718283cadSAlexander Duyck 36818283cadSAlexander Duyck /* Attempt to enable MSI-X with requested value */ 36918283cadSAlexander Duyck v_budget = pci_enable_msix_range(interface->pdev, 37018283cadSAlexander Duyck interface->msix_entries, 37118283cadSAlexander Duyck MIN_MSIX_COUNT(hw), 37218283cadSAlexander Duyck v_budget); 37318283cadSAlexander Duyck if (v_budget < 0) { 37418283cadSAlexander Duyck kfree(interface->msix_entries); 37518283cadSAlexander Duyck interface->msix_entries = NULL; 37618283cadSAlexander Duyck return -ENOMEM; 37718283cadSAlexander Duyck } 37818283cadSAlexander Duyck 37918283cadSAlexander Duyck /* record the number of queues available for q_vectors */ 38018283cadSAlexander Duyck interface->num_q_vectors = v_budget - NON_Q_VECTORS(hw); 38118283cadSAlexander Duyck 38218283cadSAlexander Duyck return 0; 38318283cadSAlexander Duyck } 38418283cadSAlexander Duyck 38518283cadSAlexander Duyck static void fm10k_init_reta(struct fm10k_intfc *interface) 38618283cadSAlexander Duyck { 38718283cadSAlexander Duyck u16 i, rss_i = interface->ring_feature[RING_F_RSS].indices; 38818283cadSAlexander Duyck u32 reta, base; 38918283cadSAlexander Duyck 39018283cadSAlexander Duyck /* If the netdev is initialized we have to maintain table if possible */ 39118283cadSAlexander Duyck if (interface->netdev->reg_state) { 39218283cadSAlexander Duyck for (i = FM10K_RETA_SIZE; i--;) { 39318283cadSAlexander Duyck reta = interface->reta[i]; 39418283cadSAlexander Duyck if ((((reta << 24) >> 24) < rss_i) && 39518283cadSAlexander Duyck (((reta << 16) >> 24) < rss_i) && 39618283cadSAlexander Duyck (((reta << 8) >> 24) < rss_i) && 39718283cadSAlexander Duyck (((reta) >> 24) < rss_i)) 39818283cadSAlexander Duyck continue; 39918283cadSAlexander Duyck goto repopulate_reta; 40018283cadSAlexander Duyck } 40118283cadSAlexander Duyck 40218283cadSAlexander Duyck /* do nothing if all of the elements are in bounds */ 40318283cadSAlexander Duyck return; 40418283cadSAlexander Duyck } 40518283cadSAlexander Duyck 40618283cadSAlexander Duyck repopulate_reta: 40718283cadSAlexander Duyck /* Populate the redirection table 4 entries at a time. To do this 40818283cadSAlexander Duyck * we are generating the results for n and n+2 and then interleaving 40918283cadSAlexander Duyck * those with the results with n+1 and n+3. 41018283cadSAlexander Duyck */ 41118283cadSAlexander Duyck for (i = FM10K_RETA_SIZE; i--;) { 41218283cadSAlexander Duyck /* first pass generates n and n+2 */ 41318283cadSAlexander Duyck base = ((i * 0x00040004) + 0x00020000) * rss_i; 41418283cadSAlexander Duyck reta = (base & 0x3F803F80) >> 7; 41518283cadSAlexander Duyck 41618283cadSAlexander Duyck /* second pass generates n+1 and n+3 */ 41718283cadSAlexander Duyck base += 0x00010001 * rss_i; 41818283cadSAlexander Duyck reta |= (base & 0x3F803F80) << 1; 41918283cadSAlexander Duyck 42018283cadSAlexander Duyck interface->reta[i] = reta; 42118283cadSAlexander Duyck } 42218283cadSAlexander Duyck } 42318283cadSAlexander Duyck 42418283cadSAlexander Duyck /** 42518283cadSAlexander Duyck * fm10k_init_queueing_scheme - Determine proper queueing scheme 42618283cadSAlexander Duyck * @interface: board private structure to initialize 42718283cadSAlexander Duyck * 42818283cadSAlexander Duyck * We determine which queueing scheme to use based on... 42918283cadSAlexander Duyck * - Hardware queue count (num_*_queues) 43018283cadSAlexander Duyck * - defined by miscellaneous hardware support/features (RSS, etc.) 43118283cadSAlexander Duyck **/ 43218283cadSAlexander Duyck int fm10k_init_queueing_scheme(struct fm10k_intfc *interface) 43318283cadSAlexander Duyck { 43418283cadSAlexander Duyck int err; 43518283cadSAlexander Duyck 43618283cadSAlexander Duyck /* Number of supported queues */ 43718283cadSAlexander Duyck fm10k_set_num_queues(interface); 43818283cadSAlexander Duyck 43918283cadSAlexander Duyck /* Configure MSI-X capability */ 44018283cadSAlexander Duyck err = fm10k_init_msix_capability(interface); 44118283cadSAlexander Duyck if (err) { 44218283cadSAlexander Duyck dev_err(&interface->pdev->dev, 44318283cadSAlexander Duyck "Unable to initialize MSI-X capability\n"); 44418283cadSAlexander Duyck return err; 44518283cadSAlexander Duyck } 44618283cadSAlexander Duyck 44718283cadSAlexander Duyck /* Allocate memory for queues */ 44818283cadSAlexander Duyck err = fm10k_alloc_q_vectors(interface); 44918283cadSAlexander Duyck if (err) 45018283cadSAlexander Duyck return err; 45118283cadSAlexander Duyck 45218283cadSAlexander Duyck /* Initialize RSS redirection table */ 45318283cadSAlexander Duyck fm10k_init_reta(interface); 45418283cadSAlexander Duyck 45518283cadSAlexander Duyck return 0; 45618283cadSAlexander Duyck } 45718283cadSAlexander Duyck 45818283cadSAlexander Duyck /** 45918283cadSAlexander Duyck * fm10k_clear_queueing_scheme - Clear the current queueing scheme settings 46018283cadSAlexander Duyck * @interface: board private structure to clear queueing scheme on 46118283cadSAlexander Duyck * 46218283cadSAlexander Duyck * We go through and clear queueing specific resources and reset the structure 46318283cadSAlexander Duyck * to pre-load conditions 46418283cadSAlexander Duyck **/ 46518283cadSAlexander Duyck void fm10k_clear_queueing_scheme(struct fm10k_intfc *interface) 46618283cadSAlexander Duyck { 46718283cadSAlexander Duyck fm10k_free_q_vectors(interface); 46818283cadSAlexander Duyck fm10k_reset_msix_capability(interface); 46918283cadSAlexander Duyck } 470