4 * Copyright 2017 6WIND S.A.
5 * Copyright 2017 Mellanox.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
36 #include "failsafe_private.h"
39 fs_eth_dev_conf_apply(struct rte_eth_dev *dev,
40 struct sub_device *sdev)
42 struct rte_eth_dev *edev;
43 struct rte_vlan_filter_conf *vfc1;
44 struct rte_vlan_filter_conf *vfc2;
50 for (i = 0; i < dev->data->nb_rx_queues; i++) {
53 rxq = dev->data->rx_queues[i];
54 ret = rte_eth_rx_queue_setup(PORT_ID(sdev), i,
55 rxq->info.nb_desc, rxq->socket_id,
56 &rxq->info.conf, rxq->info.mp);
58 ERROR("rx_queue_setup failed");
63 for (i = 0; i < dev->data->nb_tx_queues; i++) {
66 txq = dev->data->tx_queues[i];
67 ret = rte_eth_tx_queue_setup(PORT_ID(sdev), i,
68 txq->info.nb_desc, txq->socket_id,
71 ERROR("tx_queue_setup failed");
75 /* dev_link.link_status */
76 if (dev->data->dev_link.link_status !=
77 edev->data->dev_link.link_status) {
78 DEBUG("Configuring link_status");
79 if (dev->data->dev_link.link_status)
80 ret = rte_eth_dev_set_link_up(PORT_ID(sdev));
82 ret = rte_eth_dev_set_link_down(PORT_ID(sdev));
84 ERROR("Failed to apply link_status");
88 DEBUG("link_status already set");
91 if (dev->data->promiscuous != edev->data->promiscuous) {
92 DEBUG("Configuring promiscuous");
93 if (dev->data->promiscuous)
94 rte_eth_promiscuous_enable(PORT_ID(sdev));
96 rte_eth_promiscuous_disable(PORT_ID(sdev));
98 DEBUG("promiscuous already set");
101 if (dev->data->all_multicast != edev->data->all_multicast) {
102 DEBUG("Configuring all_multicast");
103 if (dev->data->all_multicast)
104 rte_eth_allmulticast_enable(PORT_ID(sdev));
106 rte_eth_allmulticast_disable(PORT_ID(sdev));
108 DEBUG("all_multicast already set");
111 if (dev->data->mtu != edev->data->mtu) {
112 DEBUG("Configuring MTU");
113 ret = rte_eth_dev_set_mtu(PORT_ID(sdev), dev->data->mtu);
115 ERROR("Failed to apply MTU");
119 DEBUG("MTU already set");
122 DEBUG("Configuring default MAC address");
123 ret = rte_eth_dev_default_mac_addr_set(PORT_ID(sdev),
124 &dev->data->mac_addrs[0]);
126 ERROR("Setting default MAC address failed");
130 if (PRIV(dev)->nb_mac_addr > 1)
131 DEBUG("Configure additional MAC address%s",
132 (PRIV(dev)->nb_mac_addr > 2 ? "es" : ""));
133 for (i = 1; i < PRIV(dev)->nb_mac_addr; i++) {
134 struct ether_addr *ea;
136 ea = &dev->data->mac_addrs[i];
137 ret = rte_eth_dev_mac_addr_add(PORT_ID(sdev), ea,
138 PRIV(dev)->mac_addr_pool[i]);
140 char ea_fmt[ETHER_ADDR_FMT_SIZE];
142 ether_format_addr(ea_fmt, ETHER_ADDR_FMT_SIZE, ea);
143 ERROR("Adding MAC address %s failed", ea_fmt);
147 vfc1 = &dev->data->vlan_filter_conf;
148 vfc2 = &edev->data->vlan_filter_conf;
149 if (memcmp(vfc1, vfc2, sizeof(struct rte_vlan_filter_conf))) {
155 DEBUG("Configuring VLAN filter");
156 for (i = 0; i < RTE_DIM(vfc1->ids); i++) {
157 if (vfc1->ids[i] == 0)
162 /* count trailing zeroes */
163 vbit = ~ids & (ids - 1);
164 /* clear least significant bit set */
165 ids ^= (ids ^ (ids - 1)) ^ vbit;
166 for (; vbit; vlan_id++)
168 ret = rte_eth_dev_vlan_filter(
169 PORT_ID(sdev), vlan_id, 1);
171 ERROR("Failed to apply VLAN filter %hu",
178 DEBUG("VLAN filter already set");
184 failsafe_eth_dev_state_sync(struct rte_eth_dev *dev)
186 struct sub_device *sdev;
191 if (PRIV(dev)->state < DEV_PROBED)
193 ret = failsafe_eal_init(dev);
196 if (PRIV(dev)->state < DEV_ACTIVE)
199 FOREACH_SUBDEV(sdev, i, dev)
200 if (sdev->state == DEV_PROBED)
201 inactive |= UINT32_C(1) << i;
202 ret = dev->dev_ops->dev_configure(dev);
205 FOREACH_SUBDEV(sdev, i, dev) {
206 if (inactive & (UINT32_C(1) << i)) {
207 ret = fs_eth_dev_conf_apply(dev, sdev);
209 ERROR("Could not apply configuration to sub_device %d",
211 /* TODO: disable device */
217 * If new devices have been configured, check if
218 * the link state has changed.
221 dev->dev_ops->link_update(dev, 1);
222 if (PRIV(dev)->state < DEV_STARTED)
224 ret = dev->dev_ops->dev_start(dev);