1 /*- 2 * BSD LICENSE 3 * 4 * Copyright 2015 6WIND S.A. 5 * Copyright 2015 Mellanox. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of 6WIND S.A. nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <rte_ether.h> 35 #include <rte_ethdev.h> 36 #include <rte_interrupts.h> 37 #include <rte_alarm.h> 38 39 #include "mlx5.h" 40 #include "mlx5_rxtx.h" 41 #include "mlx5_utils.h" 42 43 /** 44 * DPDK callback to start the device. 45 * 46 * Simulate device start by attaching all configured flows. 47 * 48 * @param dev 49 * Pointer to Ethernet device structure. 50 * 51 * @return 52 * 0 on success, negative errno value on failure. 53 */ 54 int 55 mlx5_dev_start(struct rte_eth_dev *dev) 56 { 57 struct priv *priv = dev->data->dev_private; 58 int err; 59 60 if (mlx5_is_secondary()) 61 return -E_RTE_SECONDARY; 62 63 priv_lock(priv); 64 if (priv->started) { 65 priv_unlock(priv); 66 return 0; 67 } 68 /* Update Rx/Tx callback. */ 69 priv_select_tx_function(priv); 70 priv_select_rx_function(priv); 71 DEBUG("%p: allocating and configuring hash RX queues", (void *)dev); 72 err = priv_create_hash_rxqs(priv); 73 if (!err) 74 err = priv_rehash_flows(priv); 75 if (!err) 76 priv->started = 1; 77 else { 78 ERROR("%p: an error occurred while configuring hash RX queues:" 79 " %s", 80 (void *)priv, strerror(err)); 81 goto error; 82 } 83 if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_NONE) 84 priv_fdir_enable(priv); 85 err = priv_flow_start(priv); 86 if (err) { 87 priv->started = 0; 88 ERROR("%p: an error occurred while configuring flows:" 89 " %s", 90 (void *)priv, strerror(err)); 91 goto error; 92 } 93 err = priv_rx_intr_vec_enable(priv); 94 if (err) { 95 ERROR("%p: RX interrupt vector creation failed", 96 (void *)priv); 97 goto error; 98 } 99 priv_dev_interrupt_handler_install(priv, dev); 100 priv_xstats_init(priv); 101 priv_unlock(priv); 102 return 0; 103 error: 104 /* Rollback. */ 105 priv_special_flow_disable_all(priv); 106 priv_mac_addrs_disable(priv); 107 priv_destroy_hash_rxqs(priv); 108 priv_flow_stop(priv); 109 priv_unlock(priv); 110 return -err; 111 } 112 113 /** 114 * DPDK callback to stop the device. 115 * 116 * Simulate device stop by detaching all configured flows. 117 * 118 * @param dev 119 * Pointer to Ethernet device structure. 120 */ 121 void 122 mlx5_dev_stop(struct rte_eth_dev *dev) 123 { 124 struct priv *priv = dev->data->dev_private; 125 126 if (mlx5_is_secondary()) 127 return; 128 129 priv_lock(priv); 130 if (!priv->started) { 131 priv_unlock(priv); 132 return; 133 } 134 DEBUG("%p: cleaning up and destroying hash RX queues", (void *)dev); 135 priv_special_flow_disable_all(priv); 136 priv_mac_addrs_disable(priv); 137 priv_destroy_hash_rxqs(priv); 138 priv_fdir_disable(priv); 139 priv_flow_stop(priv); 140 priv_rx_intr_vec_disable(priv); 141 priv_dev_interrupt_handler_uninstall(priv, dev); 142 priv->started = 0; 143 priv_unlock(priv); 144 } 145