// SPDX-License-Identifier: GPL-2.0 /* Copyright(c) 2013 - 2018 Intel Corporation. */ #include <linux/net/intel/libie/rx.h> #include "iavf.h" #include "iavf_prototype.h" /* All iavf tracepoints are defined by the include below, which must * be included exactly once across the whole kernel with * CREATE_TRACE_POINTS defined */ #define CREATE_TRACE_POINTS #include "iavf_trace.h" static int iavf_setup_all_tx_resources(struct iavf_adapter *adapter); static int iavf_setup_all_rx_resources(struct iavf_adapter *adapter); static int iavf_close(struct net_device *netdev); static void iavf_init_get_resources(struct iavf_adapter *adapter); static int iavf_check_reset_complete(struct iavf_hw *hw); char iavf_driver_name[] = …; static const char iavf_driver_string[] = …; static const char iavf_copyright[] = …; /* iavf_pci_tbl - PCI Device ID Table * * Wildcard entries (PCI_ANY_ID) should come last * Last entry must be all 0s * * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, * Class, Class Mask, private data (not used) } */ static const struct pci_device_id iavf_pci_tbl[] = …; MODULE_DEVICE_TABLE(pci, iavf_pci_tbl); MODULE_ALIAS(…) …; MODULE_DESCRIPTION(…) …; MODULE_IMPORT_NS(…); MODULE_IMPORT_NS(…); MODULE_LICENSE(…) …; static const struct net_device_ops iavf_netdev_ops; int iavf_status_to_errno(enum iavf_status status) { … } int virtchnl_status_to_errno(enum virtchnl_status_code v_status) { … } /** * iavf_pdev_to_adapter - go from pci_dev to adapter * @pdev: pci_dev pointer */ static struct iavf_adapter *iavf_pdev_to_adapter(struct pci_dev *pdev) { … } /** * iavf_is_reset_in_progress - Check if a reset is in progress * @adapter: board private structure */ static bool iavf_is_reset_in_progress(struct iavf_adapter *adapter) { … } /** * iavf_wait_for_reset - Wait for reset to finish. * @adapter: board private structure * * Returns 0 if reset finished successfully, negative on timeout or interrupt. */ int iavf_wait_for_reset(struct iavf_adapter *adapter) { … } /** * iavf_allocate_dma_mem_d - OS specific memory alloc for shared code * @hw: pointer to the HW structure * @mem: ptr to mem struct to fill out * @size: size of memory requested * @alignment: what to align the allocation to **/ enum iavf_status iavf_allocate_dma_mem_d(struct iavf_hw *hw, struct iavf_dma_mem *mem, u64 size, u32 alignment) { … } /** * iavf_free_dma_mem - wrapper for DMA memory freeing * @hw: pointer to the HW structure * @mem: ptr to mem struct to free **/ enum iavf_status iavf_free_dma_mem(struct iavf_hw *hw, struct iavf_dma_mem *mem) { … } /** * iavf_allocate_virt_mem - virt memory alloc wrapper * @hw: pointer to the HW structure * @mem: ptr to mem struct to fill out * @size: size of memory requested **/ enum iavf_status iavf_allocate_virt_mem(struct iavf_hw *hw, struct iavf_virt_mem *mem, u32 size) { … } /** * iavf_free_virt_mem - virt memory free wrapper * @hw: pointer to the HW structure * @mem: ptr to mem struct to free **/ void iavf_free_virt_mem(struct iavf_hw *hw, struct iavf_virt_mem *mem) { … } /** * iavf_schedule_reset - Set the flags and schedule a reset event * @adapter: board private structure * @flags: IAVF_FLAG_RESET_PENDING or IAVF_FLAG_RESET_NEEDED **/ void iavf_schedule_reset(struct iavf_adapter *adapter, u64 flags) { … } /** * iavf_schedule_aq_request - Set the flags and schedule aq request * @adapter: board private structure * @flags: requested aq flags **/ void iavf_schedule_aq_request(struct iavf_adapter *adapter, u64 flags) { … } /** * iavf_tx_timeout - Respond to a Tx Hang * @netdev: network interface device structure * @txqueue: queue number that is timing out **/ static void iavf_tx_timeout(struct net_device *netdev, unsigned int txqueue) { … } /** * iavf_misc_irq_disable - Mask off interrupt generation on the NIC * @adapter: board private structure **/ static void iavf_misc_irq_disable(struct iavf_adapter *adapter) { … } /** * iavf_misc_irq_enable - Enable default interrupt generation settings * @adapter: board private structure **/ static void iavf_misc_irq_enable(struct iavf_adapter *adapter) { … } /** * iavf_irq_disable - Mask off interrupt generation on the NIC * @adapter: board private structure **/ static void iavf_irq_disable(struct iavf_adapter *adapter) { … } /** * iavf_irq_enable_queues - Enable interrupt for all queues * @adapter: board private structure **/ static void iavf_irq_enable_queues(struct iavf_adapter *adapter) { … } /** * iavf_irq_enable - Enable default interrupt generation settings * @adapter: board private structure * @flush: boolean value whether to run rd32() **/ void iavf_irq_enable(struct iavf_adapter *adapter, bool flush) { … } /** * iavf_msix_aq - Interrupt handler for vector 0 * @irq: interrupt number * @data: pointer to netdev **/ static irqreturn_t iavf_msix_aq(int irq, void *data) { … } /** * iavf_msix_clean_rings - MSIX mode Interrupt Handler * @irq: interrupt number * @data: pointer to a q_vector **/ static irqreturn_t iavf_msix_clean_rings(int irq, void *data) { … } /** * iavf_map_vector_to_rxq - associate irqs with rx queues * @adapter: board private structure * @v_idx: interrupt number * @r_idx: queue number **/ static void iavf_map_vector_to_rxq(struct iavf_adapter *adapter, int v_idx, int r_idx) { … } /** * iavf_map_vector_to_txq - associate irqs with tx queues * @adapter: board private structure * @v_idx: interrupt number * @t_idx: queue number **/ static void iavf_map_vector_to_txq(struct iavf_adapter *adapter, int v_idx, int t_idx) { … } /** * iavf_map_rings_to_vectors - Maps descriptor rings to vectors * @adapter: board private structure to initialize * * This function maps descriptor rings to the queue-specific vectors * we were allotted through the MSI-X enabling code. Ideally, we'd have * one vector per ring/queue, but on a constrained vector budget, we * group the rings as "efficiently" as possible. You would add new * mapping configurations in here. **/ static void iavf_map_rings_to_vectors(struct iavf_adapter *adapter) { … } /** * iavf_irq_affinity_notify - Callback for affinity changes * @notify: context as to what irq was changed * @mask: the new affinity mask * * This is a callback function used by the irq_set_affinity_notifier function * so that we may register to receive changes to the irq affinity masks. **/ static void iavf_irq_affinity_notify(struct irq_affinity_notify *notify, const cpumask_t *mask) { … } /** * iavf_irq_affinity_release - Callback for affinity notifier release * @ref: internal core kernel usage * * This is a callback function used by the irq_set_affinity_notifier function * to inform the current notification subscriber that they will no longer * receive notifications. **/ static void iavf_irq_affinity_release(struct kref *ref) { … } /** * iavf_request_traffic_irqs - Initialize MSI-X interrupts * @adapter: board private structure * @basename: device basename * * Allocates MSI-X vectors for tx and rx handling, and requests * interrupts from the kernel. **/ static int iavf_request_traffic_irqs(struct iavf_adapter *adapter, char *basename) { … } /** * iavf_request_misc_irq - Initialize MSI-X interrupts * @adapter: board private structure * * Allocates MSI-X vector 0 and requests interrupts from the kernel. This * vector is only for the admin queue, and stays active even when the netdev * is closed. **/ static int iavf_request_misc_irq(struct iavf_adapter *adapter) { … } /** * iavf_free_traffic_irqs - Free MSI-X interrupts * @adapter: board private structure * * Frees all MSI-X vectors other than 0. **/ static void iavf_free_traffic_irqs(struct iavf_adapter *adapter) { … } /** * iavf_free_misc_irq - Free MSI-X miscellaneous vector * @adapter: board private structure * * Frees MSI-X vector 0. **/ static void iavf_free_misc_irq(struct iavf_adapter *adapter) { … } /** * iavf_configure_tx - Configure Transmit Unit after Reset * @adapter: board private structure * * Configure the Tx unit of the MAC after a reset. **/ static void iavf_configure_tx(struct iavf_adapter *adapter) { … } /** * iavf_configure_rx - Configure Receive Unit after Reset * @adapter: board private structure * * Configure the Rx unit of the MAC after a reset. **/ static void iavf_configure_rx(struct iavf_adapter *adapter) { … } /** * iavf_find_vlan - Search filter list for specific vlan filter * @adapter: board private structure * @vlan: vlan tag * * Returns ptr to the filter object or NULL. Must be called while holding the * mac_vlan_list_lock. **/ static struct iavf_vlan_filter *iavf_find_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan) { … } /** * iavf_add_vlan - Add a vlan filter to the list * @adapter: board private structure * @vlan: VLAN tag * * Returns ptr to the filter object or NULL when no memory available. **/ static struct iavf_vlan_filter *iavf_add_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan) { … } /** * iavf_del_vlan - Remove a vlan filter from the list * @adapter: board private structure * @vlan: VLAN tag **/ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan) { … } /** * iavf_restore_filters * @adapter: board private structure * * Restore existing non MAC filters when VF netdev comes back up **/ static void iavf_restore_filters(struct iavf_adapter *adapter) { … } /** * iavf_get_num_vlans_added - get number of VLANs added * @adapter: board private structure */ u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter) { … } /** * iavf_get_max_vlans_allowed - get maximum VLANs allowed for this VF * @adapter: board private structure * * This depends on the negotiated VLAN capability. For VIRTCHNL_VF_OFFLOAD_VLAN, * do not impose a limit as that maintains current behavior and for * VIRTCHNL_VF_OFFLOAD_VLAN_V2, use the maximum allowed sent from the PF. **/ static u16 iavf_get_max_vlans_allowed(struct iavf_adapter *adapter) { … } /** * iavf_max_vlans_added - check if maximum VLANs allowed already exist * @adapter: board private structure **/ static bool iavf_max_vlans_added(struct iavf_adapter *adapter) { … } /** * iavf_vlan_rx_add_vid - Add a VLAN filter to a device * @netdev: network device struct * @proto: unused protocol data * @vid: VLAN tag **/ static int iavf_vlan_rx_add_vid(struct net_device *netdev, __always_unused __be16 proto, u16 vid) { … } /** * iavf_vlan_rx_kill_vid - Remove a VLAN filter from a device * @netdev: network device struct * @proto: unused protocol data * @vid: VLAN tag **/ static int iavf_vlan_rx_kill_vid(struct net_device *netdev, __always_unused __be16 proto, u16 vid) { … } /** * iavf_find_filter - Search filter list for specific mac filter * @adapter: board private structure * @macaddr: the MAC address * * Returns ptr to the filter object or NULL. Must be called while holding the * mac_vlan_list_lock. **/ static struct iavf_mac_filter *iavf_find_filter(struct iavf_adapter *adapter, const u8 *macaddr) { … } /** * iavf_add_filter - Add a mac filter to the filter list * @adapter: board private structure * @macaddr: the MAC address * * Returns ptr to the filter object or NULL when no memory available. **/ struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter, const u8 *macaddr) { … } /** * iavf_replace_primary_mac - Replace current primary address * @adapter: board private structure * @new_mac: new MAC address to be applied * * Replace current dev_addr and send request to PF for removal of previous * primary MAC address filter and addition of new primary MAC filter. * Return 0 for success, -ENOMEM for failure. * * Do not call this with mac_vlan_list_lock! **/ static int iavf_replace_primary_mac(struct iavf_adapter *adapter, const u8 *new_mac) { … } /** * iavf_is_mac_set_handled - wait for a response to set MAC from PF * @netdev: network interface device structure * @macaddr: MAC address to set * * Returns true on success, false on failure */ static bool iavf_is_mac_set_handled(struct net_device *netdev, const u8 *macaddr) { … } /** * iavf_set_mac - NDO callback to set port MAC address * @netdev: network interface device structure * @p: pointer to an address structure * * Returns 0 on success, negative on failure */ static int iavf_set_mac(struct net_device *netdev, void *p) { … } /** * iavf_addr_sync - Callback for dev_(mc|uc)_sync to add address * @netdev: the netdevice * @addr: address to add * * Called by __dev_(mc|uc)_sync when an address needs to be added. We call * __dev_(uc|mc)_sync from .set_rx_mode and guarantee to hold the hash lock. */ static int iavf_addr_sync(struct net_device *netdev, const u8 *addr) { … } /** * iavf_addr_unsync - Callback for dev_(mc|uc)_sync to remove address * @netdev: the netdevice * @addr: address to add * * Called by __dev_(mc|uc)_sync when an address needs to be removed. We call * __dev_(uc|mc)_sync from .set_rx_mode and guarantee to hold the hash lock. */ static int iavf_addr_unsync(struct net_device *netdev, const u8 *addr) { … } /** * iavf_promiscuous_mode_changed - check if promiscuous mode bits changed * @adapter: device specific adapter */ bool iavf_promiscuous_mode_changed(struct iavf_adapter *adapter) { … } /** * iavf_set_rx_mode - NDO callback to set the netdev filters * @netdev: network interface device structure **/ static void iavf_set_rx_mode(struct net_device *netdev) { … } /** * iavf_napi_enable_all - enable NAPI on all queue vectors * @adapter: board private structure **/ static void iavf_napi_enable_all(struct iavf_adapter *adapter) { … } /** * iavf_napi_disable_all - disable NAPI on all queue vectors * @adapter: board private structure **/ static void iavf_napi_disable_all(struct iavf_adapter *adapter) { … } /** * iavf_configure - set up transmit and receive data structures * @adapter: board private structure **/ static void iavf_configure(struct iavf_adapter *adapter) { … } /** * iavf_up_complete - Finish the last steps of bringing up a connection * @adapter: board private structure * * Expects to be called while holding crit_lock. **/ static void iavf_up_complete(struct iavf_adapter *adapter) { … } /** * iavf_clear_mac_vlan_filters - Remove mac and vlan filters not sent to PF * yet and mark other to be removed. * @adapter: board private structure **/ static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter) { … } /** * iavf_clear_cloud_filters - Remove cloud filters not sent to PF yet and * mark other to be removed. * @adapter: board private structure **/ static void iavf_clear_cloud_filters(struct iavf_adapter *adapter) { … } /** * iavf_clear_fdir_filters - Remove fdir filters not sent to PF yet and mark * other to be removed. * @adapter: board private structure **/ static void iavf_clear_fdir_filters(struct iavf_adapter *adapter) { … } /** * iavf_clear_adv_rss_conf - Remove adv rss conf not sent to PF yet and mark * other to be removed. * @adapter: board private structure **/ static void iavf_clear_adv_rss_conf(struct iavf_adapter *adapter) { … } /** * iavf_down - Shutdown the connection processing * @adapter: board private structure * * Expects to be called while holding crit_lock. **/ void iavf_down(struct iavf_adapter *adapter) { … } /** * iavf_acquire_msix_vectors - Setup the MSIX capability * @adapter: board private structure * @vectors: number of vectors to request * * Work with the OS to set up the MSIX vectors needed. * * Returns 0 on success, negative on failure **/ static int iavf_acquire_msix_vectors(struct iavf_adapter *adapter, int vectors) { … } /** * iavf_free_queues - Free memory for all rings * @adapter: board private structure to initialize * * Free all of the memory associated with queue pairs. **/ static void iavf_free_queues(struct iavf_adapter *adapter) { … } /** * iavf_set_queue_vlan_tag_loc - set location for VLAN tag offload * @adapter: board private structure * * Based on negotiated capabilities, the VLAN tag needs to be inserted and/or * stripped in certain descriptor fields. Instead of checking the offload * capability bits in the hot path, cache the location the ring specific * flags. */ void iavf_set_queue_vlan_tag_loc(struct iavf_adapter *adapter) { … } /** * iavf_alloc_queues - Allocate memory for all rings * @adapter: board private structure to initialize * * We allocate one ring per queue at run-time since we don't know the * number of queues at compile-time. The polling_netdev array is * intended for Multiqueue, but should work fine with a single queue. **/ static int iavf_alloc_queues(struct iavf_adapter *adapter) { … } /** * iavf_set_interrupt_capability - set MSI-X or FAIL if not supported * @adapter: board private structure to initialize * * Attempt to configure the interrupts using the best available * capabilities of the hardware and the kernel. **/ static int iavf_set_interrupt_capability(struct iavf_adapter *adapter) { … } /** * iavf_config_rss_aq - Configure RSS keys and lut by using AQ commands * @adapter: board private structure * * Return 0 on success, negative on failure **/ static int iavf_config_rss_aq(struct iavf_adapter *adapter) { … } /** * iavf_config_rss_reg - Configure RSS keys and lut by writing registers * @adapter: board private structure * * Returns 0 on success, negative on failure **/ static int iavf_config_rss_reg(struct iavf_adapter *adapter) { … } /** * iavf_config_rss - Configure RSS keys and lut * @adapter: board private structure * * Returns 0 on success, negative on failure **/ int iavf_config_rss(struct iavf_adapter *adapter) { … } /** * iavf_fill_rss_lut - Fill the lut with default values * @adapter: board private structure **/ static void iavf_fill_rss_lut(struct iavf_adapter *adapter) { … } /** * iavf_init_rss - Prepare for RSS * @adapter: board private structure * * Return 0 on success, negative on failure **/ static int iavf_init_rss(struct iavf_adapter *adapter) { … } /** * iavf_alloc_q_vectors - Allocate memory for interrupt vectors * @adapter: board private structure to initialize * * We allocate one q_vector per queue interrupt. If allocation fails we * return -ENOMEM. **/ static int iavf_alloc_q_vectors(struct iavf_adapter *adapter) { … } /** * iavf_free_q_vectors - Free memory allocated for interrupt vectors * @adapter: board private structure to initialize * * This function frees the memory allocated to the q_vectors. In addition if * NAPI is enabled it will delete any references to the NAPI struct prior * to freeing the q_vector. **/ static void iavf_free_q_vectors(struct iavf_adapter *adapter) { … } /** * iavf_reset_interrupt_capability - Reset MSIX setup * @adapter: board private structure * **/ static void iavf_reset_interrupt_capability(struct iavf_adapter *adapter) { … } /** * iavf_init_interrupt_scheme - Determine if MSIX is supported and init * @adapter: board private structure to initialize * **/ static int iavf_init_interrupt_scheme(struct iavf_adapter *adapter) { … } /** * iavf_free_interrupt_scheme - Undo what iavf_init_interrupt_scheme does * @adapter: board private structure **/ static void iavf_free_interrupt_scheme(struct iavf_adapter *adapter) { … } /** * iavf_free_rss - Free memory used by RSS structs * @adapter: board private structure **/ static void iavf_free_rss(struct iavf_adapter *adapter) { … } /** * iavf_reinit_interrupt_scheme - Reallocate queues and vectors * @adapter: board private structure * @running: true if adapter->state == __IAVF_RUNNING * * Returns 0 on success, negative on failure **/ static int iavf_reinit_interrupt_scheme(struct iavf_adapter *adapter, bool running) { … } /** * iavf_finish_config - do all netdev work that needs RTNL * @work: our work_struct * * Do work that needs both RTNL and crit_lock. **/ static void iavf_finish_config(struct work_struct *work) { … } /** * iavf_schedule_finish_config - Set the flags and schedule a reset event * @adapter: board private structure **/ void iavf_schedule_finish_config(struct iavf_adapter *adapter) { … } /** * iavf_process_aq_command - process aq_required flags * and sends aq command * @adapter: pointer to iavf adapter structure * * Returns 0 on success * Returns error code if no command was sent * or error code if the command failed. **/ static int iavf_process_aq_command(struct iavf_adapter *adapter) { … } /** * iavf_set_vlan_offload_features - set VLAN offload configuration * @adapter: board private structure * @prev_features: previous features used for comparison * @features: updated features used for configuration * * Set the aq_required bit(s) based on the requested features passed in to * configure VLAN stripping and/or VLAN insertion if supported. Also, schedule * the watchdog if any changes are requested to expedite the request via * virtchnl. **/ static void iavf_set_vlan_offload_features(struct iavf_adapter *adapter, netdev_features_t prev_features, netdev_features_t features) { … } /** * iavf_startup - first step of driver startup * @adapter: board private structure * * Function process __IAVF_STARTUP driver state. * When success the state is changed to __IAVF_INIT_VERSION_CHECK * when fails the state is changed to __IAVF_INIT_FAILED **/ static void iavf_startup(struct iavf_adapter *adapter) { … } /** * iavf_init_version_check - second step of driver startup * @adapter: board private structure * * Function process __IAVF_INIT_VERSION_CHECK driver state. * When success the state is changed to __IAVF_INIT_GET_RESOURCES * when fails the state is changed to __IAVF_INIT_FAILED **/ static void iavf_init_version_check(struct iavf_adapter *adapter) { … } /** * iavf_parse_vf_resource_msg - parse response from VIRTCHNL_OP_GET_VF_RESOURCES * @adapter: board private structure */ int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter) { … } /** * iavf_init_get_resources - third step of driver startup * @adapter: board private structure * * Function process __IAVF_INIT_GET_RESOURCES driver state and * finishes driver initialization procedure. * When success the state is changed to __IAVF_DOWN * when fails the state is changed to __IAVF_INIT_FAILED **/ static void iavf_init_get_resources(struct iavf_adapter *adapter) { … } /** * iavf_init_send_offload_vlan_v2_caps - part of initializing VLAN V2 caps * @adapter: board private structure * * Function processes send of the extended VLAN V2 capability message to the * PF. Must clear IAVF_EXTENDED_CAP_RECV_VLAN_V2 if the message is not sent, * e.g. due to PF not negotiating VIRTCHNL_VF_OFFLOAD_VLAN_V2. */ static void iavf_init_send_offload_vlan_v2_caps(struct iavf_adapter *adapter) { … } /** * iavf_init_recv_offload_vlan_v2_caps - part of initializing VLAN V2 caps * @adapter: board private structure * * Function processes receipt of the extended VLAN V2 capability message from * the PF. **/ static void iavf_init_recv_offload_vlan_v2_caps(struct iavf_adapter *adapter) { … } /** * iavf_init_process_extended_caps - Part of driver startup * @adapter: board private structure * * Function processes __IAVF_INIT_EXTENDED_CAPS driver state. This state * handles negotiating capabilities for features which require an additional * message. * * Once all extended capabilities exchanges are finished, the driver will * transition into __IAVF_INIT_CONFIG_ADAPTER. */ static void iavf_init_process_extended_caps(struct iavf_adapter *adapter) { … } /** * iavf_init_config_adapter - last part of driver startup * @adapter: board private structure * * After all the supported capabilities are negotiated, then the * __IAVF_INIT_CONFIG_ADAPTER state will finish driver initialization. */ static void iavf_init_config_adapter(struct iavf_adapter *adapter) { … } /** * iavf_watchdog_task - Periodic call-back task * @work: pointer to work_struct **/ static void iavf_watchdog_task(struct work_struct *work) { … } /** * iavf_disable_vf - disable VF * @adapter: board private structure * * Set communication failed flag and free all resources. * NOTE: This function is expected to be called with crit_lock being held. **/ static void iavf_disable_vf(struct iavf_adapter *adapter) { … } /** * iavf_reset_task - Call-back task to handle hardware reset * @work: pointer to work_struct * * During reset we need to shut down and reinitialize the admin queue * before we can use it to communicate with the PF again. We also clear * and reinit the rings because that context is lost as well. **/ static void iavf_reset_task(struct work_struct *work) { … } /** * iavf_adminq_task - worker thread to clean the admin queue * @work: pointer to work_struct containing our data **/ static void iavf_adminq_task(struct work_struct *work) { … } /** * iavf_free_all_tx_resources - Free Tx Resources for All Queues * @adapter: board private structure * * Free all transmit software resources **/ void iavf_free_all_tx_resources(struct iavf_adapter *adapter) { … } /** * iavf_setup_all_tx_resources - allocate all queues Tx resources * @adapter: board private structure * * If this function returns with an error, then it's possible one or * more of the rings is populated (while the rest are not). It is the * callers duty to clean those orphaned rings. * * Return 0 on success, negative on failure **/ static int iavf_setup_all_tx_resources(struct iavf_adapter *adapter) { … } /** * iavf_setup_all_rx_resources - allocate all queues Rx resources * @adapter: board private structure * * If this function returns with an error, then it's possible one or * more of the rings is populated (while the rest are not). It is the * callers duty to clean those orphaned rings. * * Return 0 on success, negative on failure **/ static int iavf_setup_all_rx_resources(struct iavf_adapter *adapter) { … } /** * iavf_free_all_rx_resources - Free Rx Resources for All Queues * @adapter: board private structure * * Free all receive software resources **/ void iavf_free_all_rx_resources(struct iavf_adapter *adapter) { … } /** * iavf_validate_tx_bandwidth - validate the max Tx bandwidth * @adapter: board private structure * @max_tx_rate: max Tx bw for a tc **/ static int iavf_validate_tx_bandwidth(struct iavf_adapter *adapter, u64 max_tx_rate) { … } /** * iavf_validate_ch_config - validate queue mapping info * @adapter: board private structure * @mqprio_qopt: queue parameters * * This function validates if the config provided by the user to * configure queue channels is valid or not. Returns 0 on a valid * config. **/ static int iavf_validate_ch_config(struct iavf_adapter *adapter, struct tc_mqprio_qopt_offload *mqprio_qopt) { … } /** * iavf_del_all_cloud_filters - delete all cloud filters on the traffic classes * @adapter: board private structure **/ static void iavf_del_all_cloud_filters(struct iavf_adapter *adapter) { … } /** * iavf_is_tc_config_same - Compare the mqprio TC config with the * TC config already configured on this adapter. * @adapter: board private structure * @mqprio_qopt: TC config received from kernel. * * This function compares the TC config received from the kernel * with the config already configured on the adapter. * * Return: True if configuration is same, false otherwise. **/ static bool iavf_is_tc_config_same(struct iavf_adapter *adapter, struct tc_mqprio_qopt *mqprio_qopt) { … } /** * __iavf_setup_tc - configure multiple traffic classes * @netdev: network interface device structure * @type_data: tc offload data * * This function processes the config information provided by the * user to configure traffic classes/queue channels and packages the * information to request the PF to setup traffic classes. * * Returns 0 on success. **/ static int __iavf_setup_tc(struct net_device *netdev, void *type_data) { … } /** * iavf_parse_cls_flower - Parse tc flower filters provided by kernel * @adapter: board private structure * @f: pointer to struct flow_cls_offload * @filter: pointer to cloud filter structure */ static int iavf_parse_cls_flower(struct iavf_adapter *adapter, struct flow_cls_offload *f, struct iavf_cloud_filter *filter) { … } /** * iavf_handle_tclass - Forward to a traffic class on the device * @adapter: board private structure * @tc: traffic class index on the device * @filter: pointer to cloud filter structure */ static int iavf_handle_tclass(struct iavf_adapter *adapter, u32 tc, struct iavf_cloud_filter *filter) { … } /** * iavf_find_cf - Find the cloud filter in the list * @adapter: Board private structure * @cookie: filter specific cookie * * Returns ptr to the filter object or NULL. Must be called while holding the * cloud_filter_list_lock. */ static struct iavf_cloud_filter *iavf_find_cf(struct iavf_adapter *adapter, unsigned long *cookie) { … } /** * iavf_configure_clsflower - Add tc flower filters * @adapter: board private structure * @cls_flower: Pointer to struct flow_cls_offload */ static int iavf_configure_clsflower(struct iavf_adapter *adapter, struct flow_cls_offload *cls_flower) { … } /** * iavf_delete_clsflower - Remove tc flower filters * @adapter: board private structure * @cls_flower: Pointer to struct flow_cls_offload */ static int iavf_delete_clsflower(struct iavf_adapter *adapter, struct flow_cls_offload *cls_flower) { … } /** * iavf_setup_tc_cls_flower - flower classifier offloads * @adapter: board private structure * @cls_flower: pointer to flow_cls_offload struct with flow info */ static int iavf_setup_tc_cls_flower(struct iavf_adapter *adapter, struct flow_cls_offload *cls_flower) { … } /** * iavf_setup_tc_block_cb - block callback for tc * @type: type of offload * @type_data: offload data * @cb_priv: * * This function is the block callback for traffic classes **/ static int iavf_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) { … } static LIST_HEAD(iavf_block_cb_list); /** * iavf_setup_tc - configure multiple traffic classes * @netdev: network interface device structure * @type: type of offload * @type_data: tc offload data * * This function is the callback to ndo_setup_tc in the * netdev_ops. * * Returns 0 on success **/ static int iavf_setup_tc(struct net_device *netdev, enum tc_setup_type type, void *type_data) { … } /** * iavf_restore_fdir_filters * @adapter: board private structure * * Restore existing FDIR filters when VF netdev comes back up. **/ static void iavf_restore_fdir_filters(struct iavf_adapter *adapter) { … } /** * iavf_open - Called when a network interface is made active * @netdev: network interface device structure * * Returns 0 on success, negative value on failure * * The open entry point is called when a network interface is made * active by the system (IFF_UP). At this point all resources needed * for transmit and receive operations are allocated, the interrupt * handler is registered with the OS, the watchdog is started, * and the stack is notified that the interface is ready. **/ static int iavf_open(struct net_device *netdev) { … } /** * iavf_close - Disables a network interface * @netdev: network interface device structure * * Returns 0, this is not allowed to fail * * The close entry point is called when an interface is de-activated * by the OS. The hardware is still under the drivers control, but * needs to be disabled. All IRQs except vector 0 (reserved for admin queue) * are freed, along with all transmit and receive resources. **/ static int iavf_close(struct net_device *netdev) { … } /** * iavf_change_mtu - Change the Maximum Transfer Unit * @netdev: network interface device structure * @new_mtu: new value for maximum frame size * * Returns 0 on success, negative on failure **/ static int iavf_change_mtu(struct net_device *netdev, int new_mtu) { … } /** * iavf_disable_fdir - disable Flow Director and clear existing filters * @adapter: board private structure **/ static void iavf_disable_fdir(struct iavf_adapter *adapter) { … } #define NETIF_VLAN_OFFLOAD_FEATURES … /** * iavf_set_features - set the netdev feature flags * @netdev: ptr to the netdev being adjusted * @features: the feature set that the stack is suggesting * Note: expects to be called while under rtnl_lock() **/ static int iavf_set_features(struct net_device *netdev, netdev_features_t features) { … } /** * iavf_features_check - Validate encapsulated packet conforms to limits * @skb: skb buff * @dev: This physical port's netdev * @features: Offload features that the stack believes apply **/ static netdev_features_t iavf_features_check(struct sk_buff *skb, struct net_device *dev, netdev_features_t features) { … } /** * iavf_get_netdev_vlan_hw_features - get NETDEV VLAN features that can toggle on/off * @adapter: board private structure * * Depending on whether VIRTHCNL_VF_OFFLOAD_VLAN or VIRTCHNL_VF_OFFLOAD_VLAN_V2 * were negotiated determine the VLAN features that can be toggled on and off. **/ static netdev_features_t iavf_get_netdev_vlan_hw_features(struct iavf_adapter *adapter) { … } /** * iavf_get_netdev_vlan_features - get the enabled NETDEV VLAN fetures * @adapter: board private structure * * Depending on whether VIRTHCNL_VF_OFFLOAD_VLAN or VIRTCHNL_VF_OFFLOAD_VLAN_V2 * were negotiated determine the VLAN features that are enabled by default. **/ static netdev_features_t iavf_get_netdev_vlan_features(struct iavf_adapter *adapter) { … } #define IAVF_NETDEV_VLAN_FEATURE_ALLOWED(requested, allowed, feature_bit) … /** * iavf_fix_netdev_vlan_features - fix NETDEV VLAN features based on support * @adapter: board private structure * @requested_features: stack requested NETDEV features **/ static netdev_features_t iavf_fix_netdev_vlan_features(struct iavf_adapter *adapter, netdev_features_t requested_features) { … } /** * iavf_fix_strip_features - fix NETDEV CRC and VLAN strip features * @adapter: board private structure * @requested_features: stack requested NETDEV features * * Returns fixed-up features bits **/ static netdev_features_t iavf_fix_strip_features(struct iavf_adapter *adapter, netdev_features_t requested_features) { … } /** * iavf_fix_features - fix up the netdev feature bits * @netdev: our net device * @features: desired feature bits * * Returns fixed-up features bits **/ static netdev_features_t iavf_fix_features(struct net_device *netdev, netdev_features_t features) { … } static const struct net_device_ops iavf_netdev_ops = …; /** * iavf_check_reset_complete - check that VF reset is complete * @hw: pointer to hw struct * * Returns 0 if device is ready to use, or -EBUSY if it's in reset. **/ static int iavf_check_reset_complete(struct iavf_hw *hw) { … } /** * iavf_process_config - Process the config information we got from the PF * @adapter: board private structure * * Verify that we have a valid config struct, and set up our netdev features * and our VSI struct. **/ int iavf_process_config(struct iavf_adapter *adapter) { … } /** * iavf_probe - Device Initialization Routine * @pdev: PCI device information struct * @ent: entry in iavf_pci_tbl * * Returns 0 on success, negative on failure * * iavf_probe initializes an adapter identified by a pci_dev structure. * The OS initialization, configuring of the adapter private structure, * and a hardware reset occur. **/ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { … } /** * iavf_suspend - Power management suspend routine * @dev_d: device info pointer * * Called when the system (VM) is entering sleep/suspend. **/ static int iavf_suspend(struct device *dev_d) { … } /** * iavf_resume - Power management resume routine * @dev_d: device info pointer * * Called when the system (VM) is resumed from sleep/suspend. **/ static int iavf_resume(struct device *dev_d) { … } /** * iavf_remove - Device Removal Routine * @pdev: PCI device information struct * * iavf_remove is called by the PCI subsystem to alert the driver * that it should release a PCI device. The could be caused by a * Hot-Plug event, or because the driver is going to be removed from * memory. **/ static void iavf_remove(struct pci_dev *pdev) { … } /** * iavf_shutdown - Shutdown the device in preparation for a reboot * @pdev: pci device structure **/ static void iavf_shutdown(struct pci_dev *pdev) { … } static DEFINE_SIMPLE_DEV_PM_OPS(iavf_pm_ops, iavf_suspend, iavf_resume); static struct pci_driver iavf_driver = …; /** * iavf_init_module - Driver Registration Routine * * iavf_init_module is the first routine called when the driver is * loaded. All it does is register with the PCI subsystem. **/ static int __init iavf_init_module(void) { … } module_init(…) …; /** * iavf_exit_module - Driver Exit Cleanup Routine * * iavf_exit_module is called just before the driver is removed * from memory. **/ static void __exit iavf_exit_module(void) { … } module_exit(iavf_exit_module); /* iavf_main.c */